Forum: Mikrocontroller und Digitale Elektronik UART Übertragungsproblem


von Daniel H. (daniel1412)


Angehängte Dateien:

Lesenswert?

Hi Zusammen, bin jetzt seit ca. 2 Wochen fleißig dabei mich in die Welt 
der Microcontroller einzuarbeiten. Habe bis jetzt auch alles soweit 
geschafft ohne doofe Fragen in das Forum zu schreiben.

Aber jetzt ist es doch so weit.

Also ich habe ein kleine Programm geschrieben welches mir nur Testweise 
ein 8-Bit Wert senden soll.
Benutze auch einen Externen Quarz (Fuses gesetzt), da es ja mit dem 
Internen immer wieder Probleme wegen Kalibrierung gibt.

So weit so gut, ich bekomme auch immer einen Empfang in HTERM (oder auch 
Hyperterminal) aber das Zeichen ist nicht das was ich gesendet habe.
Ich weiß das meistens der Fehler in fehlerhafter Baudrate liegt, aber 
ich finde ihn einfach nicht. Habe auch schon mit dem Oszi nachgemessen 
ob die Eingestellte Baudrate auch wirklich rauskommt, und das scheint zu 
stimmen.


C-Code:
1
#include <avr/io.h>
2
 
3
#define F_CPU 3686400UL      // 3686400 Systemtakt in Hz - Definition als unsigned long beachten >> Ohne ergeben Fehler in der Berechnung
4
#define BAUD 4800UL         // Baudrate
5
#define UBRR_VAL 47      // Wert für Baudrate bei der Frequenz aus Datasheet
6
7
 
8
int main(void)
9
{
10
  UCSRB |= (1<<TXEN);    // Senden eingeschaltet
11
  UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0)|(1<<USBS);  // Zugriff auf UBRRH / Assynchron / Character Size = 8-Bit
12
13
  while(1)
14
  {
15
  
16
    
17
  
18
      UBRRH = UBRR_VAL >> 8;      //High Nibble schreiben
19
      UBRRL = UBRR_VAL;        //Low Nibbel schreiben
20
21
      while (!(UCSRA & (1<<UDRE)))  // warten bis Senden moeglich
22
        {
23
        }
24
 
25
        UDR = 0xAA;                    // schreibt den Hex-Wert auf die Schnittstelle
26
27
  }
28
29
30
}


Also der Hex Wert 0xAA sollte ja eigentlich dem Binärwert von 10101010 
entsprechen. Aber ich bekomme über HTERM immer den Wert 11010011.

Kann es irgendwie sein das HTERM bei mir da die Start- und Stoppbits 
durcheinander bringt? Eine andere Idee habe ich leider nicht mehr.

Im Anhang nochmal der Screenshot von HTERM.

Hoffe das ist nicht wieder so eine Anfängerfrage, aber ich währe 
wirklich sehr dankbar, wenn mir hier jemand weiterhelfen kann.

Gruß
Daniel

von Michael U. (amiga)


Lesenswert?

Hallo,

sieht eigentlich ok aus.
Du bist sicher, daß er mit dem Quarz läuft und nicht doch mit den 
internen 1MHz?

Gruáus Berlin
Michael

von Daniel H. (daniel1412)


Lesenswert?

Ich bin mir da schon relativ sicher mit der Frequenz.
Habe ja auch die Baudrate mit dem Oszi Kontrolliert und hier komme ich 
(mit Ablesefehler) auf ca. 4800 bits/s.

Also denke doch dass das mit der Freqenz passt.

von holger (Gast)


Lesenswert?

Du hast zwei Stopbits eingestellt. Nimm das mit dem USBS
mal ganz raus.

von Jean P. (fubu1000)


Lesenswert?

Hi,

UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0)|(1<<USBS);
Du setzt in dieser Zeile auf 2 StopBits , hast in HTERM aber nur 1 
StopBit eingestellt-

Gruß

von Michael U. (amiga)


Lesenswert?

Hallo,

gut, dann nehmen wir die Ausschlußmethode...

AVR raus, RX und TX brücken. Dann muß im Terminalprogramm das Echo der 
Eingaben kommen.
Natürlich unter der Voraussetzung, Du hast RX auch verdrahtet.

Was hast Du als Pegelwandler dran? MAX232? Stimmen da die Spannungen?

Gruß aus Berlin
Michael

von Michael U. (amiga)


Lesenswert?

Hallo,

Jean Player schrieb:
> Hi,
>
> UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0)|(1<<USBS);
> Du setzt in dieser Zeile auf 2 StopBits , hast in HTERM aber nur 1
> StopBit eingestellt-

Das stört aber hier nicht. Umgekehrt würde es stören, also Sender 1 
Stoppbit, Empfänger erwartet aber 2.

Das Stoppbit ist Ruhepegel, der kann dauern wie er will bis das nächste 
Startbit kommt.

Gruß aus Berlin
Michael

von Stefan E. (sternst)


Lesenswert?

@ holger
@ Jean Player

Irrelevant. Wenn der Sender 2 Stoppbits sendet, spielt es keine Rolle, 
ob am Empfänger 1 oder 2 Stoppbit eingestellt sind.

von Daniel H. (daniel1412)


Lesenswert?

Hmm, das war nur mal ein Test von mir, hatte leider vergessen das wieder 
rauszulöschen.

Aber auch ohne diesen Wert funktioniert es nicht. Jetzt ändern sich 
allerdings die Werte von der HTERM ausgabe auch noch.

HTERM ausgabe nochmal im Anhang.

Achsoo vielleicht sollte ich noch dazu sagen, dass die Übertragung nicht 
über RS232 funktioniert sonder per USB mit dem "mySmartUSB MK2
Version 2.11"

von Jean P. (fubu1000)


Lesenswert?

Jop Michael hast Recht. Da war ich wohl zu schnell.

Auszug ausm Datenblatt:
• Bit 3 – USBS: Stop Bit Select
This bit selects the number of stop bits to be inserted by the 
trAnsmitter. The Receiver
ignores this setting.

Gruß

von Daniel H. (daniel1412)


Lesenswert?

Also das mit der Brück von RxD zu TxD ohne den AVR geht nicht. Kann das 
evtl. an dem USB teil liegen, oder müsste der Trick auch mit dem 
mySmartUSB MK2 gehen?

von Michael U. (amiga)


Lesenswert?

Hallo,

naja, auch damit müßte ja ein Echo mit Brücke TxD-RxD gehen, ich kenne 
das Teil allerdings nicht.

Wenn es nur eine USB-seriell-Bridge zur Verfügung stellt, muß Echo 
gehen.

Gruß aus Berlin
Michael

von Daniel H. (daniel1412)


Lesenswert?

Also das mit dem Brücken geht nicht wie gesagt. Allerdings habe ich noch 
ein Testprogramm (dazu habe ich aber leider keinen c-Code) mit dem kann 
man einen String senden, und dieser wird dann auch gleich wieder 
zurückgesendet. Dieses Testprogramm funktioniert auf jeden Fall.

von Jean P. (fubu1000)


Lesenswert?

Hatte mich interressiert was das fürn Teil ist und habe die Technische 
Beschreibung mal überflogen. Haste im Treiber vom mySmartUsb auch die 
4800 Baud eingestellt ?

Gruß

von Daniel H. (daniel1412)


Lesenswert?

Ja, die Baudrate ist auch im Treiber eingestellt.

Jetzt muss ich mich korrigieren, habe nochmal alles neu angeschlossen 
und jetzt funktioniert die Brücke von TxD zu RxD auch einwandfrei. 
Kriege das gesendete wieder zurück.

Also muss das Problem wohl doch irgendwie in meinem C-Code liegen oder?

von Michael U. (amiga)


Lesenswert?

Hallo,

wohl zu warm hier heute, jetzt erst gesehen...

  while(1)
  {



      UBRRH = UBRR_VAL >> 8;      //High Nibble schreiben
      UBRRL = UBRR_VAL;        //Low Nibbel schreiben

      while (!(UCSRA & (1<<UDRE)))  // warten bis Senden moeglich
        {
        }

        UDR = 0xAA;                    // schreibt den Hex-Wert auf die 
Schnittstelle

  }



Du setzt jedesmal gleich nach dem Schreiben der Daten die Baudrate in 
Deiner Main-Loop und damit macht der UART natürlich Mist.

      UBRRH = UBRR_VAL >> 8;      //High Nibble schreiben
      UBRRL = UBRR_VAL;        //Low Nibbel schreiben

gehört natürlich zur Initialisierung VOR die While-Schleife...

Gruß aus Berlin
Michael

von Daniel H. (daniel1412)


Lesenswert?

Das ist ja der pure Wahnsinn, und daran sitze ich jetzt schon Tage.

Es funktioniert jetzt.

Vielen dank an alle dir mir Versucht haben zu helfen und vorallem danke 
Michael.

Gruß
Daniel

von Daniel H. (daniel1412)


Lesenswert?

Hmm, schade die freude war wohl zu früh.

Habe jetzt herausgefunden, das es zwar teilweise funktioniert. Dies aber 
anscheinend stark davon abhängt wann ich HTERM starte. Wenn ich öfter 
Connecte und Disconnecte, dann kommen verschiedene Werte raus. naja, 
dafür ist wohl der Wert 0xAA nicht geeignet, da er nicht genau 
unterscheiden kann welches das Start und Welches das Stoppbit ist 
oder????

Was macht man denn um solchen Datenwust zu vermeiden?

von Peter (Gast)


Lesenswert?

> Was macht man denn um solchen Datenwust zu vermeiden?
Am besten erst senden wenn den Empfänger bereit ist.

von Daniel H. (daniel1412)


Lesenswert?

Also komme ich um ein Handshake verfahren nicht vorbei??? Wollte Daten 
so einfach wie möglich nur in eine Richtung übertragen.

von kurz (Gast)


Lesenswert?

>Wollte Daten
>so einfach wie möglich nur in eine Richtung übertragen.


Und warum machst Du es nicht einfach?

Pack die Daten in einen Protokollrahmen, sende das Telegramm an den 
Empfänger. Sende das telegram einfach periodisch.
Der Empfänger nimmt die Daten nur an, wenn er das Telegramm korrekt 
erfaßt hat.

Und gut.

von Michael U. (amiga)


Lesenswert?

Hallo,

wenn der Empfänger immer aktiv ist, geht es.

Wenn die Pause zwischen 2 Datenpaketen länger ist als eine Bytedauer + 
Start + Stop und etwas Reserve, ist nur das erste Paket kaputt, beim 2. 
wird das erste Startbit dann wieder richtig erkannt.

Gruß aus Berlin
Michael

von Daniel H. (daniel1412)


Lesenswert?

Super, vielen dank. Das ist doch eine einfachere Lösung als das mit dem 
Protokoll.

Gruß
Daniel

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.