Hallo, Ich versuche interrupt gesteuert zeichen ueber den usart zu empfangen. als basis dient mir largedemo.c aus den avr-libc examples. in vmlab funktioiert der empfang einwandfrei. in real aber kein bischen. hier die relevanten codefragmente: hat jemand eine idee was ich verkehrt mache? danke eletrofux --------------- .... .. volatile struct { uint8_t rx_int: 1; } intflags; void InitUsart(void) { UCSRA = _BV(U2X); UCSRB = _BV(TXEN)|_BV(RXEN)|_BV(RXCIE); UBRRL = (F_CPU / (8 * 9600UL)) - 1; } ISR(USART_RXC_vect) { uint8_t c; c = UDR; if (bit_is_clear(UCSRA, FE)) { rxbuff = c; intflags.rx_int = 1; } } int main(void) { InitUsart(); sei(); while (1) { if (intflags.rx_int) { intflags.rx_int = 0; switch (rxbuff) { case 'h': printstr_p(PSTR("\nHelp Please help me Please")); break; } } } }
Den Code hab ich mir jetzt (noch) nicht genauer angesehen. - Welche Frequenz hat der benutzte Quarz? - Ist dem Compiler diese Frequenz auch bekannt? - Läuft der AVR auch wirklich mit dem externen Quarz, oder arbeitet er evtl. noch mit dem internen RC-Oszillator? Gruß, Magnetus
hallo, magnetus, der avr (ein atmega16) laeuft mit einem externen 16Mhz quarz. die konfiguration des quarzes habe ich mithilfe peter dannegers genauer sekunden routine getestet (bilke licht im sekunden takt). sehr kniffliges problem. mfg eletrofux
Hi, welchen Prozessor setzt Du ein? Bitte nenne uns die gewünschte Baudrate und F_CPU. Warum ist U2X gesetzt? Bitte stelle auch die Deklaration Deiner globalen Variablen ein. Gruß Fred
hi fred, ich setze den atmega16 @ 16 mhz ein. die baudrate betraegt 9600 Baud. denkst du es koennte am u2x liegen? volatile char rxbuff; mehr is ja nich. mfg eletrofux
Hallo eletrofux, > ich setze den atmega16 @ 16 mhz ein. die baudrate betraegt > 9600 Baud. denkst du es koennte am u2x liegen? Dann stimmt Deine Berechnung für UBRR(L/H)! Schreibe aber besser UBRR=...; obwohl der Wert in ein Byte passt und UBRRH bei RESET 0 ist. Weshalb hast Du auch TXEN gesetzt? (Ich nehme mal an, Deine Ausgabe geschieht über den UART?) Ich schaue mir Deinen Code gleich noch einmal im Detail an. Gruß Fred
hi fred, ohne TXEN kein senden via USARt möglich. die usart routinen habe ich unterschlagen. sind aber defaultkram. TX funktioniert mit den USART settings im übrigen sehr gut. also die ausgabe von zeichen klappt problemlos. allein mit dem receive interrupt hat es was. bin leider im moment nicht in hardwarenaehe und kann daher nichts ueberpruefen. u2x werde ich aufjedenfall mal rausnehmen. wenn dir sonst noch etwas auffaellt. bidde einfach losposten :) danke eletrofux
1 | void InitUsart(void) |
2 | {
|
3 | UCSRA = _BV(U2X); |
4 | UCSRB = _BV(TXEN)|_BV(RXEN)|_BV(RXCIE); |
5 | UBRRL = (F_CPU / (8 * 9600UL)) - 1; |
6 | }
|
UBRRL = (16000000/(8*9600))-1) = 207 Bei gesetztem U2X ergibt das tatsächlich die gewünschten 9600 Baud. Mir fällt gerade auf, dass du UCSRC nicht initialisierst. Durch das Nichtinitialisieren läuft dein USART schon mal mit nur 5 Bits an Stelle der (vermutlich) gewünschen 8 Bits. Gruß, Magnetus
Hallo, im Code sehe ich nur einen echten Fehler: FE ist nur bis zum Lesen von UDR gültig -- Du solltest den Code also so ändern, dass zuerst der Status, dann UDR gelesen werden. Kann Dein Terminal (oder was immer Du zur Kommunikation einsetzt) denn die Strings vom ATmega lesen? Gruß Fred
Magnus Müller wrote: > Mir fällt gerade auf, dass du UCSRC nicht initialisierst. Durch das > Nichtinitialisieren läuft dein USART schon mal mit nur 5 Bits an Stelle > der (vermutlich) gewünschen 8 Bits. Ups... Quatsch mit Soße...! Hab gerade gesehen, dass die Wortlänge nach Reset standardmäßig auf 8 Bit gesetzt ist (schäm) Gruß, Magnetus
Hallo Magnetus, > Mir fällt gerade auf, dass du UCSRC nicht initialisierst. Durch das > Nichtinitialisieren läuft dein USART schon mal mit nur 5 Bits an Stelle Das sehe ich anders, denn nach einem RESET gilt: UCSZ0=UCSZ1=1, also 8 Bit! Viele Grüße Fred
@Fred S. Zu langsam ;P Trotzdem danke für den Hinweis ;)
Hi Magnetus,
> Zu langsam ;P
12:15 = 12:15 :-)
Gruß
Fred
Hi eletrofux, > u2x werde ich aufjedenfall mal rausnehmen. wenn dir > sonst noch etwas auffaellt. bidde einfach losposten :) Nein, lass es drin (siehe Posts von Magnetus und mir)! Gruß Fred
magnetus: jomei! mich hätest beinahe ueberzeugt ;) hallo fred, udr und status auslesen werd ich dann mal verdrehen. mein terminal ist ein stinknormaler pc mit uart und minicom als terminalsoftware. mein terminal zeigt mir gesendete ascii zeichen wie erwartet an. mfg eletrofux
Hi eletrofux, > mein terminal ist ein stinknormaler pc mit uart und > minicom als terminalsoftware. ... > mein terminal zeigt mir gesendete ascii zeichen wie > erwartet an. Das beweist zwar noch nicht, dass das Problem nicht an einer kleinen Abweichung der Baudate hängt, macht das aber sehr unwahrscheinlich. Nimm doch die Fehlererkennung erst einmal ganz aus der ISR heraus (DOR überprüfst Du ja auch nicht). Viel Erfolg, Fred
Hallo, Danke mal an alle beiteiligten. Werde Freds Rat folgen und mal den FE check entfernen. sollte das nciht funktionieren werde ich mal mit den baudrate settings herumspielen... mal hoeher, mal niedriger. mal mit mal ohne u2x. wenn das alles nicht fruchtet werde ich mich montags nochmal melden. dann aber mit dem kompletten code. schoenes wochenende mitnand' eletrofux
eletrofux wrote: > Hallo, > > Danke mal an alle beiteiligten. Werde Freds Rat folgen und > mal den FE check entfernen. Du kannst ja auch mal testen ob die ISR überhaupt aufgerufen wird. Led an einen Portpin und in der ISR einschalten.
karl heinz: guter tip. werd ich probieren. tschü eletrofux
Hallo Karl heinz, > Du kannst ja auch mal testen ob die ISR überhaupt aufgerufen > wird. Led an einen Portpin und in der ISR einschalten. Danke, dass Du hier eine so effektive wie einfache Debugging-Hilfe erwähnst. Das mit der LED hätte ich selbst auch so gemacht, aber eben nicht vorgeschlagen. Viele Fragen würden sich von selbst erledigen, wenn jeder so simple Methoden einsetzte. Ich glaube immer noch, dass der undefinierte Status von FE das Hauptproblem oben ist. Gruß Fred
Es ist nicht leicht zu blinke leds zurueck zu kehren wenn man bereits dabei zeichenketten durch den UART zu jagen :)
Hi eletrofux, > Es ist nicht leicht zu blinke leds zurueck zu kehren > wenn man bereits dabei zeichenketten durch den UART > zu jagen :) Doch -- aber wenn die UART-Kommunikation erst einmal klappt, dann machst Du die Fehlersuche, indem Du den uC Zeichenketten via UART ausgeben lässt. Damit ist dann das "Blinke-LED-Stadium" überwunden. Aber ab und zu muss man doch wieder dahin zurück... Viele Grüße Fred
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.