Hallo, kann kein Zeichen über die UART empfangen. Hat jemand eine Idee? #include <avr/io.h> //#include <uart.h> //#include <avr/delay.h> int main(void) { UCSRB = 0x08; //UART TX einschalten UCSRC = 0xC6; UBRRH = 0x00; UBRRL = 0x17; while (UCSRA & 0x20) //warten bis Senden möglich { UDR = 0x78; //schreibt das Zeichen x auf die Schnittstelle } //return 0; }
AVR-GCC-Tutorial/Der UART Schau dir den Code an, vergleich mit deinem. Und PS: beim ersten mal ist es eine gute Idee, wenn der µC in einer Endlosschleife auf Dauersenden geht. Das macht die Fehlersuche ungleich einfacher, als wie wenn er nach einem Power-On nur ein einzelnes Zeichen sendet und sich dann wieder schlafen legt. AVR Checkliste Abschnitt 3.2
Sepp Horst schrieb: > funktioniert noch immer nicht -.- Was? Sepp Horst schrieb: > Hallo, kann kein Zeichen über die UART empfangen. Hat jemand eine Idee? Funktioniert deine Hardware? Hast du schon mal den uC ausgesteckt, die Pins RX+TX gebrückt und vom PC aus ein Zeichen gesendet und sofort das selbe Zeichen wieder empfangen (das wäre ein sogenannter Loopback)?
UCSRB = 0x08; //UART TX einschalten Willst du nicht empfangen?
Ah du willst den µC Senden lassen. Gewöhn dir erstmal eine andere Schreibweise an, um die bits zu setzten. UCSRB = 0x08; UCSR0 |= (1<<TXEN); oder wie das bei deinem Controller heißt Dann Schau ob die Baudeinstellungen stimmen: UBRRH = 0x00; UBRRL = 0x17; Ist das mit der Formel berechnet, bzw aus der Tabelle entnommen? UCSRC = 0xC6; Richtige zusammensetzung? Standart wäre 8N1 ?? Und welche Taktrate hat dein µC. Wenn die nicht zur Baudeinstellung passt, kanns nicht gehen. Zudem mal einen Externen Quarz anschließen, damit der Fehler bei der Baudrate geringer wird
Was ist denn an dieser Schreibweise > UCSRB = 0x08; auszusetzen? ich finde das leserlicher als > UCSR0 |= (1<<TXEN);
dummschwaetzer schrieb: > Was ist denn an dieser Schreibweise >> UCSRB = 0x08; > auszusetzen? > ich finde das leserlicher als >> UCSR0 |= (1<<TXEN); Was daran leserlicher ist? Es geht nicht nur um Leserlicher, sondern darum das ich bits setzte und nicht ein ganzes Byte. Zum Thema Leserlichkeit: Was sagt mir 0x08 aus? 00001000 Toll jetzt weiß ich das ein Bit gesetzt ist, nur was macht das? UCSR0 |= (1<<TXEN); Ah, das ist das TX bit. Ich will das ganze jetzt auf einen anderen AVR Transportieren, also tausche ich nurnoch die Bitbezeichnungen aus und alles geht. So muss ich jedes Bit vergleichen, wie es bei dem anderen heißt. dummschwaetzer = Troll??
mach ich alt #define Konstante1 0x08U;//Bit3 #define Konstante2 0x04U;//Bit2 Register_irgendwas = Konstante1 + Konstante2;//Setze Bit 3 und 2 Register_irgendwas &= ~ Konstante2;//Lösche Bit 2 bei geeigneter Konstantenbenennung finde ich das übersichtlicher und ich kann mehrere Bits auf einmal setzen / löschen.
dummschwaetzer schrieb: > bei geeigneter Konstantenbenennung finde ich das übersichtlicher und ich > kann mehrere Bits auf einmal setzen / löschen. Na dann übertrag das mal auf einen anderne µC aus der gleichen Familie, bei dem die Bits zwar im gleichen Register aber an einer anderen Position sitzen. Bei der Variante UCSRB |= ( 1 << TXEN ) | ( 1 << RXEN ); brauch ich genau gar nichts tun und kann direkt im Code lesen, dass sowohl Sender als auch Empfänger eingeschaltet werden. Ich bin nicht darauf angewiesen, dass da irgendein Kommentar daneben steht (der dann auch noch tunlichst stimmen sollte) und ich bin nicht darauf angewiesen da irgendwelche Konstante einzuführen, die ebenfalls wieder falsch sein können. Wenn dir die Schreibweise 1<<Bitname nicht gefällt, dann versteck sie meinetwegen in einem Makro #define BIT(x) (1<<(x)) dann kannst du schreiben UCSRB |= BIT(TXEN) | BIT(RXEN); Aber lass die Finger davon, selber die Bits in Hex-Zahlen umzurechnen! Genau damit man das eben nicht machen muss, sind die Bitnamen alle vordefiniert. Und zwar so, dass sie ohne dein Zutun zum jeweiligen µC passen. Ideal wäre es noch, wenn sie dann auch noch so definiert wären, dass man ein falsches Bit im falschen Register gar nicht erst benennen kann, aber das ist zum jetzigen Zeitpunkt ohne massive Umstellung der Headerfilegenerierung und der Systematik nicht machbar. Aber wahrscheinlich findest du ach das
1 | UDR = 0x78; //schreibt das Zeichen x auf die Schnittstelle |
lesbarer als das
1 | UDR = 'x'; |
(auch so ein Unsinn. Wenn ich ein Zeichen ausgeben will, dann schreibe ich es direkt hin und nicht seinen ASCII Code in Hex.)
Register_irgendwas = Konstante1 + Konstante2; So und jetz will ich Bit 5 Setzten und weiß nicht was vorher schon gesetzt war. Also muss ich schreiben Bit 5 + bit 1 + bit 2, muss alle Konstanten definiert haben etc. etc. Das ganze Bitdefinitionen steht schon im Datenblatt drin, und haben einen sinnvollen Namen (wenn man weiß was sie heißen). Sowas gibt es nicht ohne grund. Das ich mal einen Portzustand mit 0xFF oder 0x00 oder 0xF0 setzte ist natürlich einfacher, als wenn ich 0b00000000 oder 0b11111111 oder gar PORTX|= (1<<0) | (1<<1) | ... je nach Beispiel. Aber gerade bei Konfigurationsgeschichten ist das eine Sache die ungemein bei einer Fehlersuche hilft, da der Code absolut verständlich ist.
Mike Mike schrieb: > Ich will das ganze jetzt auf einen anderen AVR Transportieren, also > tausche ich nurnoch die Bitbezeichnungen aus und alles geht. in der Hoffnung das das Bit im gleich Register gemeint ist. Das das ist, finde ich der größte nachteil. Das bit und Register nicht gewarnt werden wenn sie nicht zusammenpassen. Man müsste eine enum für jedes Register anlegen.
Peter II schrieb: > Mike Mike schrieb: >> Ich will das ganze jetzt auf einen anderen AVR Transportieren, also >> tausche ich nurnoch die Bitbezeichnungen aus und alles geht. > > in der Hoffnung das das Bit im gleich Register gemeint ist. Das das ist, > finde ich der größte nachteil. Das bit und Register nicht gewarnt werden > wenn sie nicht zusammenpassen. Man müsste eine enum für jedes Register > anlegen. Da hast du auch wieder recht, aber das kann man am Ende vom Datenblatt immer schön mit der Tabelle vergleichen. Da ist jedes Register und der dazugehörige Bitname aufgelistet.
Sepp Horst schrieb: > funktioniert noch immer nicht -.- Zurück zum Sepp Horst Was hast du alles gemacht? Bist du die Checkliste durchgegangen? * Hast du den Loopbacktest gemacht? * Hast du den Timingtest gemacht? * Bist du auf Dauersenden gegangen?
kbuchegg schrieb: > Bei der Variante > > UCSRB |= ( 1 << TXEN ) | ( 1 << RXEN ); und wo sinr TXEN Bzw RXEN definiert? meine Variante: irgendwo in der Header-Datei des Schaltkreises #define TXEN 0x01; #define RXEN 0x02; im Programm: Uart_Register = TXEN + RXEN; vergleiche mit: UCSRB |= ( 1 << TXEN ) | ( 1 << RXEN ); mikeii schrieb: > So und jetz will ich Bit 5 Setzten und weiß nicht was vorher schon > gesetzt war. > Also muss ich schreiben Bit 5 + bit 1 + bit 2, muss alle Konstanten > definiert haben etc. etc. port_neuer_inhalt |= 0x20u; Und wenn die 0x20u einen guten Namen uber #define erhalten haben: port_neuer_inhalt |= guter_name; > dummschwaetzer = Troll?? dummschwaetzer != Troll was macht da eigentlich der Kompiler daraus? ist das dann im ASM-File mit "<<" mehr Code?
dummschwaetzer schrieb: > kbuchegg schrieb: >> Bei der Variante >> >> UCSRB |= ( 1 << TXEN ) | ( 1 << RXEN ); > > und wo sinr TXEN Bzw RXEN definiert? in der Entsprechenden ioXXXX.h die zur Controllerfamilie (oder Typ?) gehört > meine Variante: > irgendwo in der Header-Datei des Schaltkreises > #define TXEN 0x01; > #define RXEN 0x02; > > im Programm: > Uart_Register = TXEN + RXEN; > > vergleiche mit: > UCSRB |= ( 1 << TXEN ) | ( 1 << RXEN ); Wofür alles definieren was schon da ist? Einmal die avr/io.h einbinden und gut ist > mikeii schrieb: >> So und jetz will ich Bit 5 Setzten und weiß nicht was vorher schon >> gesetzt war. >> Also muss ich schreiben Bit 5 + bit 1 + bit 2, muss alle Konstanten >> definiert haben etc. etc. > > port_neuer_inhalt |= 0x20u; > Und wenn die 0x20u einen guten Namen uber #define erhalten haben: > port_neuer_inhalt |= guter_name; Ich kanns mir auch noch schwerer machen... >> dummschwaetzer = Troll?? > > dummschwaetzer != Troll eher nicht Lernbereit > was macht da eigentlich der Kompiler daraus? > ist das dann im ASM-File mit "<<" mehr Code? ist SHL und SHR in Assembler. Und ich glaube nicht, dass das Bitshift mehr Speicher braucht, als die Werzuweisung. Und vom #define her ist das absolut wurscht, da das Präcompilerdirectiven sind
Mike Mike schrieb: > Und ich glaube nicht, dass das Bitshift mehr Speicher braucht, als die > Werzuweisung. das shiften macht schon der präcompiler
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.