Forum: Compiler & IDEs Baudratenquarz angeschlossen UART funktioniert nicht mehr


von Martin W. (tschini)


Angehängte Dateien:

Lesenswert?

Hallo

Für ein projekt versuche ich gerade eine verbindung zwischen pc und 
mikrocontroller über die serielle schnittstelle herzustellen. Ich 
besitze einen atmega32 und habe vorerst mit dem internen takt von 1 MHz 
gearbeitet. Da man mit diesem Takt keine gute verbindnung herstellen 
kann habe ich mir einen quarz mit 1,8432 MHz zugelegt. Seitdem ich 
diesen angeschlossen habe funktioniert die UART verbindung jedoch nicht 
mehr. Ich glaube nicht, dass ich die fuse bits falsch gesetzt habe, da 
ich den mikrocontroller problemlos programmieren kann und andere 
funktionen, wie das einschalten von LEDs noch immer funktionieren. 
gesetzt habe ich jedenfalls lfuse 0xfd und hfuse 0x99. Verwendet wird 
der quarz offensichtlich auch, denn sobald ich ihn entferne läuft nichts 
mehr.

Softwaremäßig habe ich die verbinung mit Realterm und einer selbst 
geschriebenen c# anwendung getestet. bei beiden konnte ich zuvor zeichen 
einlesen und schicken, jedoch kamen aufgrund der falschen frequenz immer 
wieder falsche zeichen an. beim virtuellen com port, beim 
mikrocontroller und bei den anwendungen habe ich jeweils folgende 
einstellungen vorgenommen: 8 Datenbits, 1 Stopbit, Baudrate: 9600. Beim 
mikrocontroller erhalte ich einen UBBR wert von 11.

Ich hoffe ich hab den schaltplan halbwegs richtig aufgezeichnet; 
vielleicht habe ich ja etwas falsch verbunden oder übersehen, was mir 
nicht auffällt. beim mx232 sind pin 13 und 14 bewusst vertauscht, da ich 
nur ein nullmodem kabel besitze.

Das Programm auf dem mikrocontroller soll einfach ein zeichen empfangen 
und das selbe wider zurücksenden:
#include <avr/io.h>
#include <inttypes.h>

#define F_CPU 1843200UL
#define USART_BAUDRATE 9600UL
#define UBBR_VALUE F_CPU/(16*USART_BAUDRATE)-1 
//(F_CPU+8*USART_BAUDRATE)/(16*USART_BAUDRATE)-1

int USARTInit()
{
   //Baudrate definieren
   UBRRL = UBBR_VALUE;
   UBRRH = (UBBR_VALUE>8);
   // 8bit 1 Stopbit
   UCSRC=(1<<URSEL)|(3<<UCSZ0);
   //Sender und Empfänger aktivieren
   UCSRB=(1<<RXEN)|(1<<TXEN);
}

// Zeichen von PC empfangen
char USARTReadChar() // gibt char zurück
{
   while(!(UCSRA & (1<<RXC))) // warten bis RX bereit
   {
   }
   return UDR; // char zurückgeben
}

// Zeichen an PC schicken
void USARTWriteChar(char data) // Übergabeparameter char
{
   while(!(UCSRA & (1<<UDRE)))// warten bis TX bereit
   {
   }
   UDR=data;
}

void main()
{
   DDRB |= (1<<PORTB0) | (1<<PORTB1); // B0 & B1 als outputs festlegen
   PORTB |= (1 << PINB0) | (1 << PINB1); // LEDs einschalten
   char data;
   USARTInit(); // USART initialisieren

   while(1)
   {
      data=USARTReadChar();
      USARTWriteChar(data);
   }
}


Ich hoffe, dass mir jemand weiterhelfen kann...
Mfg Martin

von Peter II (Gast)


Lesenswert?

lass erstmal eine LED mit einem delay_ms(1000) blinken, wenn sie 
wirklich im Sekunden takt blinkt dann stimmt der Quarz und die fuse.

von Martin W. (tschini)


Lesenswert?

Vielen dank für die schnelle Antwort scheint so als hätte der quarz eine 
andere frequenz die led ändert alle ~5s den status... kann das daran 
liegen, dass ich meine schaltung vorläufig auf einem steckbrett 
aufgebaut habe oder ist der quarz einfach mist?

von Stefan E. (sternst)


Lesenswert?

1
UBRRH = (UBBR_VALUE>8);
Du hattest einfach nur Glück, wenn dein UART mit diesem Code vorher 
funktioniert hat.

von (prx) A. K. (prx)


Lesenswert?

Für Steckbrett sicherheitshalber CKOPT programmieren, ergibt robusteren 
full swing oczillator.

von Peter II (Gast)


Lesenswert?

Martin Walchshofer schrieb:
> kann das daran
> liegen, dass ich meine schaltung vorläufig auf einem steckbrett
> aufgebaut habe oder ist der quarz einfach mist?

beides ist recht unwahrscheinlich, hast du auch die optimierung 
eingeschaltet?

von (prx) A. K. (prx)


Lesenswert?

Stefan Ernst schrieb:
> Du hattest einfach nur Glück, wenn dein
> UART mit diesem Code vorher funktioniert hat.

Bei 1MHz passt es noch, weil unterhalb von 8. Bei 1,8MHz nicht mehr.

von Martin W. (tschini)


Lesenswert?

Vielen dank für die zahlreichen antworten habe UBRRH = (UBBR_VALUE>8); 
auf UBRRH = (UBBR_VALUE>>8); so wie es auch im datenblatt steht 
geändert, jetzt funktioniert es einwandfrei :)

von blubb (Gast)


Lesenswert?

UBBR müsste sich auch als ganzes ansprechen lassen, also ohne Trennung 
in High- und Lowbyte. Habs nicht 100%ig im Kopf, aber bei einigen 16 Bit 
Registern geht das.

von (prx) A. K. (prx)


Lesenswert?

Nicht beim Mega32, weil das UBRRH der AVRs mit alter Registermap 
ziemlich verquer liegt. Das geht erst bei den Typen mit renovierter 
Registermap, wie dem Mega324.

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
Noch kein Account? Hier anmelden.