Hi Leute, ich wollte in meinem Programm warten, bis ein Zeichen an USART1 empfangen wird und darauf reagieren. Hab es ausprobiert, bis jetzt aber ohne Erfolgt. Also zum Anfang erlaube ich interrupts sei(); Und meine ISR sieht folgendermaßen aus: ISR(USART1_RXC_vect) // USART1, Rx Complete verctor: 21 { printf("USART1 ISR ok\t"); } Das was ich vom PC aus an USART1 sende, kommt auch am µC an. Jedoch wird die ISR nicht ausgeführt. Muss man sonst was beachten? Ich wollte eigentlich beim Empfang eines Zeichens in die ISR springen und da weiteren Zeichen einlesen.
>printf("USART1 ISR ok\t");
<Sarkasmus>
Sowas gehört auch unbedingt in eine ISR...
</Sarkasmus>
Hast du die Interrupt-Freigabe-Flags (RXCIE und TXIE) und die
UART-Freigabe-Flags (RXC und TXC) freigegeben?
Wirf mal ein Blick ins Datenblatt. Da sind Besipiele für den
Poll-Betrieb angegeben.
Und sonst würde auch ein grösseres Stück deines Codes etwas bringen.
Ja hmm, das sollte auch ein Test sein, ob die ISR funktioniert. Die Datenkommunikation zwischen dem PC und dem µC ist auch i.O., also was USART1 Initialisierung angeht. Nur der Einsprung in die ISR geht nicht. Aus dem Datenblat werde ich auch nicht schlauer, weil da nur ein Beispiel zu, externen IR in assembler vorhanden ist.
void usart1_init(void) { unsigned int a= 103; UBRR1H = a<<8; UBRR1L = a; UCSR1A = 0x00; UCSR1B = (1<<RXEN1) | (1<<TXEN1); UCSR1C = (1<<UCSZ11) | (1<<UCSZ10) | (1<<URSEL1); } Hier :) Und wie gesagt, ich kann über usart1 Daten senden/empfangen.
>UCSR1B = (1<<RXEN1) | (1<<TXEN1);
Muss noch erweitert werden:
UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (1<<RXCIE); // für
Empfangsinterrupt
Wirf mal einen Blick auf die USART-Register auf Seite 185ff.
>UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (1<<RXCIE); Muß natürlich >UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (1<<RXCIE1); oder so ähnlich heissen.
Ich check das irgendwie nciht. Hab jetzt so initialisiert: void usart1_init(void) { unsigned int a= 103; UBRR1H = a<<8; UBRR1L = a; UCSR1A = (1 << RXC1); UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (1<<RXCIE1); UCSR1C = (1<<UCSZ11) | (1<<UCSZ10) | (1<<URSEL1); } Als Test, will ich im Hauptprogramm eine LED leuchten lassen (die FKT funzt) sei(); char a; unsigned char dummy; ISR (USART1_RXC_vect) { cli(); eia485_led_on(); while (UCSR1A & (1<<RXC1) ) dummy = UDR1; } Und das klappt immer noch nicht :( Hab jetzt while (UCSR1A & (1<<RXC1) ) dummy = UDR1; reingetan, wegen der Beschreibung aus dem Datenblatt. When the Receive Complete Interrupt Enable (RXCIE) in UCSRB is set, the USART Receive Complete Interrupt will be executed as long as the RXC Flag is set (provided that global interrupts are enabled). When interrupt-driven data reception is used, the receive complete routine must read the received data from UDR in order to clear the RXC Flag, otherwise a new interrupt will occur once the interrupt routine terminates.
Ahh ok,. habs jetzt hinbekommen! Vielen Dank für deine Hilfe @ WM-Rahul. War ein Fehler ganz wo anders (DAO-Fehler).
Hi, > unsigned int a= 103; > UBRR1H = a<<8; > UBRR1L = a; soll wohl so nicht sein, oder? Grüße, Freakazoid
und warum nicht? Beim 16 MHz Quarz und 9600 Baud ist es richtig. Funktioniert ja auch.
Lesbarer wäre auch so was: #define Crystal 16000000 #define BAUD 9600 #define UBRR Crystal/(16*BAUD)-1 ... Damit rechnet der Preprozessor und nicht Du (nicht so fehleranfällig). Ein Wert von '103' mitten im Quellcode und dann noch als 'a' deklariert ist unschön. Außerdem läßt sich das Programm so schnell an einen neuen Quarz anpassen. Grüße, Freakazoid
#define UBRR Crystal/(16_L_*BAUD)-1 UBRR1H = (unsigned char) (UBRR>>8); UBRR1L = (unsigned char) UBRR; Um es ganz korrekt zu machen... Ist aber auch im Datenblatt beschrieben...
@Der inoffizielle WM-Rahul: Hatte das DB gerade nicht hier, aber dafür war ich schon nah dran. 103 ist jedenfalls ungut. Grüße, Freakazoid
Hab aber 103 nach der Formel da oben berechnet. Und Baud wird von mir sicherlich nicht geändert oO
Wie geasgt, UBRR ist auch vom Quarz abhängig. Letztlich ist es jedem selbst überlassen was er schon vorher ausrechnet, allerdings ist so ein Code eine ungünstige Bedingung für das Debugging - und das wurde ja hier gefordert. Grüße, Freakazoid
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.