Hallo. Ich bin ziemlich verzweifelt beim Versuch, von der seriellen Leitung zu lesen. Bitte helft! Ich benutze das aktuelle AVR Studio, AVRISP mkII, ein selbstgebasteltes board und einen hugepine USB<-> seriell-Wandler+Terminalprogramm unter WinVista Prozessor: ATXMEGA192A3 USART D0 (PinD3/D2) Problem: Im Test reagiert der µC nicht auf an ihn gesendete Daten. Auch im Simulator2 passiert überhaupt nichts, wenn ich das RXCIF Flag beim USARTD0 manuell setze. Eine Interruptversion habe ich ebenfallsausprobiert. Die I.-Routine wird aber nicht angesprungen. Zeichen zum PC senden klappt perfekt. Code ohne Interrupt: -------------------- #include <avr/io.h> #define LEDPORT PORTA #define LED 7 int main(void) { PORTD.OUTSET |= PIN3_bm; // Für den Transmitter PORTD.DIRSET |= PIN3_bm; // " //keine Clockconfig--> int. 2MHz Takt nutzen --> BSEL = 12 für 9600baud USARTD0.BAUDCTRLA = 12; // 8bit UART, no parity, 1 stopbit USARTD0.CTRLC |= USART_CMODE_ASYNCHRONEOUS_gc|USART_CHSIZE_8BIT_gc; // Receiver einschalten USARTD0.CTRLB |= USART_RXEN_bm; LEDPORT.DIRSET |= (1<<LED); while (1) { while (!(USARTD0.STATUS & USART_RXCIF_bm)); LEDPORT.OUTTGL |= (1<<LED); } return 0; } Code mit Interrupt: (***:= geändert) ------------------- #include <avr/io.h> #include <avr/interrupt.h> #define LEDPORT PORTA #define LED 7 volatile char c; // *** RXC ISR *** ISR (USARTD0_RXC_vect) { c = USARTD0.DATA; } // ********************* int main(void) { PORTD.OUTSET |= PIN3_bm; // Für den Transmitter PORTD.DIRSET |= PIN3_bm; // " //keine Clockconfig--> int. 2MHz Takt nutzen --> BSEL = 12 für 9600baud USARTD0.BAUDCTRLA = 12; // 8bit UART, no parity, 1 stopbit USARTD0.CTRLC |= USART_CMODE_ASYNCHRONEOUS_gc|USART_CHSIZE_8BIT_gc; // *** RXC Interrupt auf high priority *** USART.CTRLA |= USART_RXCINTLVL_Hi_gc; // ***************************************** // Receiver einschalten USARTD0.CTRLB |= USART_RXEN_bm; LEDPORT.DIRSET |= (1<<LED); // *** Interruptcontroller: Highlevelinterrupts aktivieren *** PMIC.CTRL |= PMIC_HILVLEN_bm; // globale Interrupts aktivieren sei(); while (1) { if (c == 111) LEDPORT.OUTTGL |= (1<<LED); } // ********************************************************** return 0; } Habe auch schon den Transceiver mitaktiviert und diverse andere Sachen probiert, u.a. eine saubere Clockconfig, PortD Dir Änderungen... Wieso kann nichts empfangen werden? Wer kann helfen? Danke im Voraus, Christian
Servus,
ChristianB schrieb:
PORTD.DIRSET |= PIN3_bm; // Für den Transmitter
PORTD.OUTSET |= PIN3_bm; // Für den Transmitter
PORTD.DIRCLR |= PIN2_bm; // Für den Reciver
Gruß Xmega
Danke. Klappt leider auch nach dem Einfügen von PORTD.DIRCLR |= PINB2_bm; nicht (PORTD-Pins sind beim Start standardmäßig alle als Eingänge konfiguriert). Ich hab schon daran gedacht, dass ich den µC zu heiß eingelötet und was kaputt gemacht habe, aber im Simulator sollte ja was passieren!? Christian
Servus,
bin es nochmals
ChristianB schrieb:
Falsch:
USARTD0.CTRLC |= USART_CMODE_ASYNCHRONEOUS_gc|USART_CHSIZE_8BIT_gc;
Richtig:
USARTD0.CTRLC |= USART_CMODE_ASYNCHRONOUS_gc | USART_CHSIZE_8BIT_gc;
(USART_CMODE_ASYNCHROEOUS_gc) = das ein Tippfehler oder Kopierfehler.
Ich bekomme eine Fehlermeldeung!
Gruß XMEGA
Hallo XMEGA, nochmals Danke dafür, dass Du Dich damit beschäftigst. Der Fehler kommt vom Abtippen. Der Code wird ohne Fehlermeldungen oder Warnungen kompiliert. Tut das Programm denn bei Dir was es soll, nach Deiner Korrektur? Gruß, Christian
Servus, ChristianB schrieb: > Tut das Programm denn bei Dir was es soll Wenn du das machen willst musst du den Port anders konfigurieren falsch: LEDPORT.DIRSET |= (1<<LED); richtig: LEDPORT.DIRTGL |= (1<<LED); Dann funktioniert dein Code auf meinen Atxmega128a1 einwandfrei. Gruß XMEGA
Zum x-ten mal nach allen möglichen Codeänderungen hab ich im Simulator das RXCIF flag gesetzt - ohne Effekt. Das USARTD0.DATA Register wird im AVR Studio Simulator 2 ebenfalls nicht richtig gelesen und ich hab allmählich den Verdacht, dass ich einen bug entdeckt habe oder ein Esel bin. Ich gebs vorerst auf und besorge mir ein Xplain. Vielleicht bin ich ja tatsächlich auf eine Unzulänglichkeit im Simulator gestoßen UND habe meine Hardware beim Löten beschädigt. Könnte auch sein, dass es daran liegt, dass nicht alle Stromversorgungspins (wohl aber die der benutzten PORTs) angeschlossen sind. Auf dem Xplain solte dann ja alles für den Xmega128A1 kompiliert problemlos laufen. Wenn noch jemandem was einfällt, bitte trotzdem posten! Nochmals Danke für die Hilfe. Gruß, Christian
PROBLEM GELÖST. Es war ein Hardwarefehler. Nachdem ich eine kaum sichtbar unterbrochene Leierbahn repariert habe, funktioniert der Code. Das erklärt noch nicht, warum es im Simulator nicht funktioniert hatte. Im Datenblatt ist das RXCIF flag als read only bezeichnet. Vielleicht hat es deshalb keinen Effekt, wenn ich es im Sim manuell setze?! Ebenso mysteriös ist mir das Datenregister. Kann man vielleicht nicht beschreiben, weil der Sim dann nicht weis, ob man in den TX Buffer oder RX Buffer schreiben will?! Wie auch immer. Der obige Code funktioniert (ohne die Tippfehler) und kann auf allen XMEGA und für alle USARTs beliebig wiederverwendet werden. Grüße, Christian
Auch wenn der Thread schon älter ist: Ich befasse mich momentan ausführlich mit dem XMega (64A1) und seinen USARTS. Bei obigem Code kann man zwar empfangen, aber nichts senden (zumindest bei mir nicht...) Habe da eine Theorie, mit der das ganze wieder funktioniert: XMEGA schrieb: > PORTD.DIRSET |= PIN3_bm; // Für den Transmitter > PORTD.OUTSET |= PIN3_bm; // Für den Transmitter > > PORTD.DIRCLR |= PIN2_bm; // Für den Reciver > > > > Gruß Xmega Besser: PORTD.OUTSET = PIN3_bm; PORTD.DIRSET = PIN3_bm; PORTD.DIRCLR = PIN2_bm; -> ohne die ODER!! Grund: Die ...SET/CLR-Register lesen wohl bei der VerODERung den Wert des Ursprungsregisters (siehe Datenblatt: "Reading this register will return the value of the DIR register."): DIRSET |= PIN3_bm ist DIRSET = DIR | PIN3_bm -> PIN3 in DIR wird 1 Das geht gut, solange nur Bits gesetzt werden, d.h. mit den ...SET-REgistern. Das tückische sind die CLR-Register: DIRCLR |= PIN2_bm ist DIRCLR = DIR | PIN2_bm -> alles was in DIR gesetzt war +PIN2 wird jetzt in DIRCLR gesetzt und somit wieder in DIR gelöscht. Es ist eben nicht DIRCLR = DIRCLR | PIN2_bm Richtig: DIRCLR = PIN2_bm -> Pin2 wird in DIRCLR gesetzt und in DIR gelöscht. Ich hoffe ich hab mich da jetzt nicht verrannt, aber wie gesagt, lasse ich die ODER weg, geht der Transmitter und der Receiver, mache ich die ODER hin, geht nur der Receiver... Vielleicht bringt dies ja dem ein oder anderen (wie mir...) die Erleuchtung.
hehe des mit den dirset und dirclr habe ich heute erst ausprobiert. Also das clr bedeutet quasi &=~ und das set bedeutet quasi |= da muss man echt aufpassen. Das steht zwar niergends aber ist verdammt wichtig. Da man sonst die ganzen register aus versehen löscht obwohl man eigentlich nur ein bit ändern wollte.
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.