ATMega32A UART läuft mit falschem Clock

OP #2948357
Lesenswert?

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?
Angehängte Dateien:
OP #2948447
Lesenswert?

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);
OP #2948487
Lesenswert?

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.
Gast #2948533
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren