Hi, ich habe Probleme mit der UART von einem ATMega32. Ich habe den Hardwareaufbau sowie die Software aus folgendem Thread genommen: http://embdev.net/topic/158895 Ansich sollen Software und Hardware wunderbar harmonieren, nur leider tun sie das bei mir nicht. Es handelt sich um einen ATMega32A der extern mit einem 10MHz Clock versorgt wird. Es ist also kein Quarz angeschlossen sondern ein Taktgeber. Die UART soll mit 38400 baud senden. Ich kann mit dem Logikanalyser erkennen, dass der Controller auch regelmäßig Daten sendet. Leider sind diese aber so langsam, dass der PC sie nicht erkennt. Ich habe mal einen Screenshot des Logikanaylzers angehängt. Auf der TXD leitung sendet der ATMega, auf der RXD Leitung sendet ein FTDI der am PC hängt. Die Fuses für den ATMega32A stehen auf: Low: 0xA0 High: 0x91 Die Einstellung für den Clock sollte mit diesen Fuses korrekt sein und ein externer clock genutzt werden. Dennoch stimmt die UART Geschwindigkeit nicht. Mit folgender Formel wird im Code die Baudrate von 38400 eingstellt: ubrr_val = ((10000000)/(38400*8L)-1); Wo liegt nun der Fehler? Oder was kann noch schief laufen und den Fehler verursachen?
Wenn ich die im Screen-Shot zu sehende Baudrate zurück rechne, dann komme ich auf einen Wert von 6 für UBRRH. Da hat dann wohl jemand URSEL nicht (korrekt) benutzt.
Also ich kenne mich mit den Eigenarten von ATMega's nicht aus. Da muss ich mal ins Datenblatt schauen wozu das Bit da ist. Der Code ist wie gesagt nicht von mir und soll angeblich funktionieren. Hier mal die komplette Sequenz mit der die UART initialisiert wird:
1 | uint16_t ubrr_val = ((10000000)/(38400*8L)-1); |
2 | UCSR0A = _BV(U2X0); |
3 | UBRR0H = (unsigned char)(ubrr_val>>8); |
4 | UBRR0L = (unsigned char)(ubrr_val & 0xFF); |
5 | UCSR0C = (1<<URSEL0) | (_BV(UCSZ00) | _BV(UCSZ01)); |
6 | UCSR0B = _BV(RXCIE0) | _BV(RXEN0); |
Star Keeper schrieb: > Hier mal die komplette Sequenz mit der die UART initialisiert wird Sicher nicht, denn da wird der Transmitter ja überhaupt nicht eingeschaltet. Wenn das wirklich die echte "komplette Sequenz" wäre, würde überhaupt nichts aus dem TXD-Pin kommen.
Jo stimmt das ist etwas komisch gemacht, das TXEN0-Bit wird erst in der Sende-Funktion in das Register geschrieben... Ich konnte mein Problem mitlerweile auch lösen, in dem ich die Bausrate erst an letzter Stelle setze. Also folgendermaßen:
1 | uint16_t ubrr_val = ((10000000)/(38400*8L)-1); |
2 | UCSR0A = _BV(U2X0); |
3 | UCSR0C = (1<<URSEL0) | (_BV(UCSZ00) | _BV(UCSZ01)); |
4 | UCSR0B = _BV(RXCIE0) | _BV(RXEN0); |
5 | |
6 | UBRR0H = (unsigned char)(ubrr_val>>8); |
7 | UBRR0L = (unsigned char)(ubrr_val & 0xFF); |
Das muss mal einer verstehen, zumal im Datenblatt die andere Reihenfolge drin steht.
Hi >Das muss mal einer verstehen, zumal im Datenblatt die andere Reihenfolge >drin steht. Das wird eigentlich über das URSEL-Bit geregelt. UCSRC und UBRRH teilen sich die gleiche IO-Adresse. Bei gesetztem URSEL-Bit wird auf UCSRC zugegriffen und bei gelöschtem auf UBRRH. Was mich etwas wundert: Das Datenblatt des ATMega32A kennt z.B. kein UCSR0A, sondern nur UCSRA. Bei den anderen Registern und Bitbezeichnern das gleiche. MfG Spess
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.