PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : USART mit Atmega8



Mr Bean
07.10.2007, 14:27
Hallo

Ich weiß dass mein Problem hier schon öfters aufgetaucht ist, ich hab mir die betreffenden Beiträge auch schon durchgelesen. Bin aber leider immernoch nicht zu einer funktionierenden Schaltung gekommen. Ich willl grad einfach das Zeichen x über die serielle Schnittstelle an meinen PC schicken und dort mit Hilfe des Hyperterminals anzeigen. Einen Max232 hab ich in meiner Schaltung drin, der scheint auch zu funktionieren. Denn wenn ich den Reset drücke werden vereinzelt Zeichen an den PC gesendent, leider nur nicht das gewollte und auch nicht konstant. D.h. wenn ich keinen Reset drücke wird gar nichts gesendet. Das Terminal hab ich auf 8Bit, 1Stoppbit, 9600Baud und keine Flusssteuerung eingestellt. vielleicht ist da auch etwas falsch. Hier mal der Code:


#include <avr/io.h>
//#include <uart.h>
//#include <avr/delay.h>

#define F_CPU 12000000L
#define BAUD 9600L

#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) //clever runde
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) //reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) //Fehler in Promille

#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
#error Systematischer Fehler in der Baudrate größer 1% und damit zu hoch!
#endif


int main(void)
{
UCSRB = (1<<TXEN); //UART TX einschalten
UCSRC = (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;

while (!(UCSRA & (1<<UDRE))) //warten bis Senden möglich
{
}

UDR = 'x'; //schreibt das Zeichen x auf die Schnittstelle

return 0;
}

Prozessor ist ein AtMega8. Der Code ist von mikrocontroller.net. Aber leicht abgewandelt. Wäre schön wenn ihr mal drüber schaun könntet. Vielleicht findet ihr ja gleich einen gravierenden Fehler...
Vielen Dank im Voraus!!

Grüße!!

Bean

Besserwessi
07.10.2007, 21:59
Zum Testen sollte man besser mehr als nur ein Zeichen senden, da fällt es leichter etwas zu erkennen. Wenn man immer das selbe zeichen sendet kann man sogar auf dem Oszilloskop eine stehendes Bild bekommen und auch ein Voltmeter kann schon weiterhelfen.

Ich sehe nicht das der TX Pin auf Ausgang geschaltet ist. Bin mir zwar nicht 100% sicher ob dass nötig ist, schaden tut es aber mit Sicherheit nicht.

Sonst mal testen ob der Prozessor wirklich mit 12 MHz läuft und nicht mit dem internen Takt (1 MHz).

Viel Spass bei der Fehlersuche.

Mr Bean
08.10.2007, 20:15
Hallo

Danke für die Hilfe, hat leider noch nichts gebracht. Die Fusebits hab ich kontrolliert. Die passen. Wie gesagt, wenn ich RESET drücke, dann wird oft ein Zeichen übertragen. Ich hab dann irgendwann einen Salat der folgendermaßen aussieht:
O ñññÏüññ ¼¼þñ¼¼üüüñ¼ü¼ü/ñ¼¼'ñOï¼O O ñý/ ñ¼þ ññ¼þ^ ¼¼üñ^Ï€ à€þÀþ€ü€þøà€€€øð À€
ððð àüø€øÀ€ € €ðø€à€ü€à øøþÀðÀð €€ÀÀ€à ø€à€ø€ € ü€ð€ð
Vielleicht fällt ja jemandem noch etwas auf an meinem Code. Ich bin so langsam ratlos, der Code ist wie gesagt von mikrocontroller.net und sollte ja eigentlich funktionieren...

Grüße!!

Bean

Mr Bean
08.10.2007, 20:54
Habs hin bekommen... =P~

Ich hab das USART jetzt mal so initialisiert wie im Datenblatt. Mit 2 Stop Bits. Da hat Der PC schon konstant ein Zeichen empfangen. Dann hab ich noch eine Wartezeit von 100ms nach dem Senden eingefügt und nun wird wie gewünscht das x übertragen. Ich wunder mich nur warum das nicht mit einem Stop bit funktioniert. Vielleicht weiß da jemand von euch was? Ich bin schon am überlegen ob mein Controller da er mit 12MHz betrieben wird einfach zu schnell ist, aber eigentlich dürfte das ja nichts ausmachen, da die Baudrate ja mit den 12MHz generriert wird.
Hier nun noch einmal der funktionierende Code:

#include <avr/io.h>
#include <avr/delay.h>

#define F_CPU 12000000L
#define BAUD 9600L

#define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1) //clever runde
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) //reale Baudrate

#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) //Fehler in Promille

#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
#error Systematischer Fehler in der Baudrate größer 1% und damit zu hoch!
#endif


int main(void)
{

UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;


UCSRB = (1<<RXEN)|(1<<TXEN); //UART TX einschalten
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); //Asynchron 8N1



while (!(UCSRA & (1<<UDRE))) //warten bis Senden möglich
{
}


UDR = 'x'; //schreibt das Zeichen x auf die Schnittstelle
_delay_ms(100);


return 0;
}


Grüße!!

Bean