UART Problem

OP #2446840
Lesenswert?

Hallo, ich verwende einen ATmega8 und möchte gerne ein Zeichen über die 
Serielleschnittstelle an einen Terminal(PC) senden.

Doch es tut sich nichts.

#include <avr/io.h>

#define F_CPU 3686400L
#define BAUD 9600L
#define UBRR_VAL = ((3686400/(9600*16))-1)

void uart_init(void) {
    UBRRH = 0x00;
  UBRRL = 0x17;


    UCSRB |= (1<<TXEN);  // UART TX einschalten
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1
}

int main(void) {
  while(1){
  while (!(UCSRA & (1<<UDRE)))  // warten bis Senden moeglich
    {
    UDR = 'x';
  }
    UDR = 'x';
  }
}


Wäre super, wenn mir jemand helfen könnte, danke.
Gast #2446896
Lesenswert?

Sepp Horst schrieb:
> #define F_CPU 3686400L
> #define BAUD 9600L
> #define UBRR_VAL = ((3686400/(9600*16))-1)

Warum definierst du eine L-Konstante, wenn du die zwei Zeilen später gar 
nicht verwendest. Und wozu wird UBRR_VAL berechnet?

Wenn du deinem Code nicht traust, kannst du besser den Ablauf im 
Simulator verfolgen (z.B. die UART Initialisierung), anstatt 
irgendwelche magischen Zahlen im Quellcode zu verteilen.

Sepp Horst schrieb:
> die geschwungene Klammer befindet sich eine Zeile darunter, müsste doch
> passen oder?
Überleg mal, was in der While-Schleife passieren soll?
Gast #2446897
Lesenswert?

>Ok, danke. Bekomme jedoch noch falsche Zeichen im Terminal. Das müsste
>doch an einer falschen Baudrate liegen? Habe im Terminal und im Programm
>auf 9600 baud, 1 Stopp - Bit gestellt, was könnte ich noch falsch
>gemacht haben?

Dein uC läuft mit falschem Takt. Vermutlich 1MHz intern RC.
Du musst die Fuses auf Crystal Osc umstellen.
UND BLOSS NICHT AUF EXTERN CLOCK!
OP #2446938
Lesenswert?

#include <avr/io.h>

#define F_CPU 3686400
#define BAUD 9600
//#define UBRR_VAL = ((3686400/(9600*16))-1)

void uart_init(void) {
    UBRRH = 0x00;
  UBRRL = 0x17;


    UCSRB |= (1<<TXEN);  // UART TX einschalten
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1
}

int main(void) {
  uart_init();
  while(1){
  while (!(UCSRA & (1<<UDRE))) {  // warten bis Senden moeglich
  }
        UDR = 'x';
    }
}
#2446952
Lesenswert?

Sepp Horst schrieb:
> Habe bei Fuses auf: Ext. Crystal/Resonator High Freq.; Start-up time:
> 16K CK + 64 ms gestellt. Ist das Richtig?

Und hat es geklappt?

(Du hast doch einen Quarz drauf? Hoffe ich zumindest)

Ich kann nur wieder auf die Checkliste verweisen.
Dort ist auch enthalten, wie man überprüfen kann, ob der µC jetzt 
tatsächlich mit der am Quarz aufgedruckten Frequenz arbeitet.
http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
#2446968
Lesenswert?

Sepp Horst schrieb:
> Habe den Quarz laut SDK - 500 Handbuch gejumpert und die Fuses
> eingestellt. Es hat sich nichts verbessert, es werden noch immer fast
> kreisrunde Zeichen  statt x ausgegeben.

Zum 35.ten mal:

Hast du KONROLLIERT, ob dein µC mit der am Quarz aufgedruckten Frequenz 
läüft oder hast du das nicht?

Es ist uninteressant was du wo reingesteckt hast und welche Fuse du wo 
umgestellt hast. Du musst KONTROLLIEREN ob dein µc mit der gewünschten 
Taktrate läuft. Vertrauen ist gut, Kontrolle ist besser.

Zu mehr als 98% sind deine Symptome auf eine falsche Taktrate 
zurückzuführen. Möglich, dass du zu den verbleibenden 2% gehörst. Aber 
solange du nicht definitiv die 98% ausschliessen kannst (und zwar 
aufgrund von Messungen), ist das erst mal die Arbeitshypothese Nummero 
Uno.
#2446988
Lesenswert?

Sepp Horst schrieb:
> Hab den Quarz mit Hilfe des Testprogrammes und einer LED getestet, er
> funktioniert.

F_CPU war auf 3696400 gestellt?
Blinken alleine ist zu wenig. Stimmt das Timing auch? Am besten mit 
einer Stoppuhr 20 mal aufblinken der LED abstoppen. Die gemessene Zeit 
sollte ziemlich genau 40 Sekunden betragen - im Rahmen der Genauigkeit 
einer Handstoppung.

(Es gibt nur die beiden Möglichkeiten
  entweder die Taktfrequenz im µC stimmt nicht
  oder das Terminalprogramm ist auf eine andere Baudrate eingestellt.

Wenn die beiden Dinge korrekt sind und die RS232 über das Jumperfeld 
richtig angestöpselt wurde (da kannst du kaum einen Fehler machen), dann 
MUSS die RS232 soweit funktioneren.

Terminal am PC zuerst hochfahren und laufen lassen. Dann erst den µC 
einschalten, wobei die Kabelverbindung schon bestehen muss. Stimmt das 
Timing, dann muss das auf Anhieb klappen.
OP #2447000
Lesenswert?

Hab da Timing gestoppt, ein Zustand am LED dauert jeweils eine Sekunde.
Hab nun versucht das Terminalprogramm zu starten, anschließend wurde die 
Verbindung mit den richtigen Einstellungen hergestellt und 
schlussendlich habe ich den µC eingeschaltet.
Resultat --> es funktioniert (also lag es an der Reihenfolge von 
Connection starten und µC einschalten)

Vielen Dank!
#2447014
Lesenswert?

Gut.

Was du dir merken musst: Du kannst dich nicht mit dem Empfänger in eine 
laufende ununterbrochene Übertragung einschalten. Der Empfänger ist 
darauf angewiesen, dass der Sender immer wieder mal eine kleine Pause in 
der Übertragung einlegt, damit er sich zu 100% sicher auf den Anfang 
eines Zeichens synchronisieren kann. Ansonsten bekommt der Empfänger Bit 
um Bit vorgesetzt und kann nicht feststellen, bei welchem Bit ein 
Zeichen anfängt.

int main(void) {
  uart_init();
  while(1){
    while (!(UCSRA & (1<<UDRE))) {  // warten bis Senden moeglich
    }
    UDR = 'x';
    _delay_ms( 10 );    // <--------
  }
}

hätte den gleichen Zweck erfüllt.

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