Forum: Mikrocontroller und Digitale Elektronik ATmega48 - IRS funktioniert nicht richtig sei()


von Johannes L. (johannes_l37)


Lesenswert?

Guten Tag, ich habe zur Zeit zwei Programme, eins das Daten über UART 
sendet, und eines welches einfach einen Counter hat und hochzählt, heute 
habe ich versucht das Counter-Programm in das UART-Sende-Programm 
einzufügen (im Endeffekt etwas zählen und dann etwas senden. ) 
Allerdings hängt er sich immer einen Befehl nach meinem sei(); d.h. er 
führt noch einen Befehl aus und macht dann gar nichts mehr. Ich 
programmiere noch nicht lange nehmt rücksicht :)
PS: Immer wenn ich etwas an PORTC setze leuchtet eine entsprechende LED, 
(PC3 ^= Rot, PC4 ^= Grün )
Interessant ist auch zu bemerken, dass die LED die ich in der IRS 
Routine aufleuchten lasse (um zu sehen ob ich da ankomme,) nicht 
leuchtet!
Ich hab wahrscheinlich etwas innerhalb der Setups (initialisierung) 
falsch gemacht.

Kann man eigentlich auch ne Variabel über Uart ausgeben? Also eine mit 
der ich z.b. den gezählten wert ausgeben :)

Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <string.h>
4
#include "globals.h" //momentan nur Deff. von Counter1
5
//Fuer Baudrate
6
#define FOSC 8000000UL // Clock Speed
7
#define BAUD 9600L
8
#define UBRR ((FOSC / (BAUD * 16L)) - 1)
9
//Fuer Baudrate - ende
10
11
12
void setup()
13
{
14
  cli(); // Interrupts deaktiviert - sicherheitshalber
15
16
    DDRC &= ~(0x01);
17
    PORTC &= ~(0x01);
18
19
//Hier will ich noch die Baudrate einstellen
20
    UBRR0H = (unsigned char)(UBRR>>8);
21
    UBRR0L = (unsigned char)UBRR;
22
    /*aktiviere Sender und empfänger (uART)*/
23
    UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0) | (1 << UDRIE0);
24
    // frame format: 8data, 1stop bit
25
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
26
//Achtung, nicht vergessen bei den Fuses
27
//CKDIV8 raus zu nehmen
28
////////////////////////////////////////////
29
30
31
    ADMUX = 0xC0;
32
    ADCSRA = 0x9A;
33
34
    //INT0 + INT1
35
    EICRA = 0x0F;// Worauf reagiert der jeweilige Interrupt?
36
    EIFR = 0x03; //???? pc?
37
    EIMSK = 0x02; // Interrupts aktivieren
38
39
    TCCR1A = 0x00; // Normal Mode
40
    TCCR0A = 0x00;  // Normal Mode
41
    TCCR0B = 0x03;//0x00 // Prescaller bei 0x00 hier Timer/counter gestoppt
42
    //TCCR1B = 0x02; //Damit Prescaller auf 8 und timer Counter wieder aktiv
43
    TCNT0 = 0x00;   // 0..255
44
    OCR0A = 0x00;   // unwichtig da Normal Mode
45
    OCR0B = 0x00;   // unwichtig da Normal Mode
46
    TIMSK0 = 0x01;  // 0x01 = 1<<TOIE0)
47
    DDRC = 0xFF ; // Für LEDs, zum überprüfen wo ich grade bin.
48
    TCCR1C = 0x00; // nur für non PWM-mode
49
    TCNT1 = 0;    //Zähl register
50
51
52
}//ende von Setup (Initalisierung)
53
54
int uart_putc(unsigned char str)
55
{
56
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
57
    {
58
    }
59
60
    UDR0 = str;                      /* sende Zeichen */
61
    return 0;
62
}
63
64
/* puts ist unabhaengig vom Controllertyp */
65
void uart_puts (char *s)
66
{
67
    while (*s)
68
  s= "t" ;
69
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
70
        uart_putc(*s);
71
        s++;
72
    }
73
}
74
75
int main(void)
76
{
77
  PORTC |= (1<<PC4) ;
78
setup() ; // Initialisierung
79
sei() ; //Hier ist das erwähnte sei() ;
80
  PORTC |= (1<<PC3) ;// wird noch ausgeführt ...
81
  PORTC = 0x00 ; // wird nichmehr ausgeführt
82
83
84
85
86
87
//Beginne zu senden, UART
88
uint8_t i=0;
89
char cstr[300]; // größe der Sende Variable
90
strcpy(cstr, "123");//Das was gesendet wird
91
while( cstr[i] != 0){ // Solange bis String Ende Zeichen
92
   uart_putc(cstr[i]); // senden
93
   i++;//zeiger hoch.
94
}
95
//Ende von senden Uart.
96
while (1) {
97
   //Unendlichkeitsschleife ... (warten auf Interrupts? Andere Befehle?)
98
}
99
100
return 0; // never reached
101
102
}//ende von Main
103
104
ISR (TIMER0_OVF_vect)
105
{PORTC = 0xFF ; // wird AUCH nicht ausgeführt
106
  // F_CPU in MHz  Aufruf ca. alle                          (EDIT)
107
  // 1             2 ms                 1/(1000000 / 8 / 256)  Sekunden
108
  // 8             0,256 ms             1/(8000000 / 8 / 256)  Sekunden
109
  // 16            0,128 ms             1/(16000000 / 8 / 256) Sekunden
110
  Counter1++;
111
}//ISR EndeISR (TIMER0_OVF_vect)

fg - Johannes

von H.Joachim S. (crazyhorse)


Lesenswert?

UCSR0B = (1<<RXCIE0)....

Du gibts den Receiver-Interupt frei, hast aber keine ISR dafür.

von Johannes L. (johannes_l37)


Lesenswert?

Jo, hab das Register entsprechend überarbeitet,
1
UCSR0B = (1<<TXEN0) | (1 << UDRIE0);
funktioniert allerdings immernoch nicht.
danke

von spess53 (Gast)


Lesenswert?

Hi

>funktioniert allerdings immernoch nicht. danke

Immer noch eine Interruptfreigabe (UDRIE) ohne Interruptroutine.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Johannes L. schrieb:

Und wenn du dann deine ISR richtig gestellt hast
(Man gibt niemals, niemals, einen Interrupt frei, für den man keine ISR 
hat. So etwas wird mit einem Prozessorreset bei jedem Interrupt 
bestraft)

> Kann man eigentlich auch ne Variabel über Uart ausgeben? Also eine mit
> der ich z.b. den gezählten wert ausgeben :)

Klar kann man.
http://www.mikrocontroller.net/articles/FAQ


(Aber stell erst mal deine uart_puts Funktion wieder richtig. Die hast 
du nämlich sauber mit deiner Änderung zerstört. Und kauf dir ein C-Buch. 
Da gibt es neben dem, was in der FAQ zum Thema Stringverarbeitung steht 
noch ein großes Kapitel für C-Einsteiger zum Thema "Strings")

von Johannes L. (johannes_l37)


Lesenswert?

Vielen dank, das Programm funktioniert jetzt soweit. Ja ich denke, dass 
mir ein C-Buch wirklich weiter helfen kann, vielen dank für eure Hilfe.
fg - Johannes

von Uwe (de0508)


Lesenswert?

Hallo

Johannes L. schrieb:
> void uart_puts (char *s)
> {
>     while (*s)
>   s= "t" ;
>     {   /* so lange *s != '\0' also ungleich dem 
"String-Endezeichen(Terminator)" */
>         uart_putc(*s);
>         s++;
>     }
> }

hier ist noch ein Fehler !

s="t";

das ergibt eine Endlosschleife !

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.