Forum: Mikrocontroller und Digitale Elektronik UART einzelne Zeichen senden


von Josia A. (Firma: Zumtobel) (josia)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

Ich bin im moment dran UART zu verstehen und dann in meinem Projekt 
anzuwenden. Als erstens versuche ich einzelne Zeichen von meinem uC und 
zu meinem uC zu senden. (später dann mit einem HC05 zum uC via 
Bluetooth)

Das ganze habe ich mir im Datenblatt angeschaut und auf: 
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART

Das Problem das ich habe ist das wenn ich ein Zeichen von meinem uC zu 
meinem PC versuche zu senden bekomme ich nur unsinn in meinem Terminal 
angezeigt...
Sieht jemand den Fehler im Code?
Ich bin über jede Antwort dankbar :).

Den Code habe ich im Dateianhang und ein Scrennshot vom Terminal.

uC: Atmega32
Seriell USB Wandler wurde an PC und uC richtig angeschlossen.

Code auf Atmel Studio 7.
terminal: HTerm 0.8.5

Mit freundlichen Grüßen
Josia

von Falk B. (falk)


Lesenswert?


von 2cents (Gast)


Lesenswert?

Josia A. schrieb:
> Ich bin über jede Antwort dankbar :).

Josia A. schrieb:
> Seriell USB Wandler wurde an PC und uC richtig angeschlossen.

Ich tippe mal auf Rx/Tx vertauscht.

Schaltplan und Foto vom Aufbau wären durchaus hilfreich.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Josia A. schrieb:
> bekomme ich nur unsinn in meinem Terminal angezeigt...
Hast duein Oszilloskop (oder einen Logikanalyzer) mit dem du mal messen 
kannst, was da unterwegs ist?

> uC: Atmega32
> Seriell USB Wandler wurde an PC und uC richtig angeschlossen.
Was ist das für ein Seriell USB-Wandler? Welche Pegel gibt der aus?

> ein Scrennshot vom Terminal.
Sieht nach falscher Baudrate aus.

> Code habe ich im Dateianhang
1
 UDR = 'x';   /* schreibt das Zeichen x auf die Schnittstelle */
Mein Tipp: das Zeichen 'x' hat das Bitmuster 01111000. Dieses Bitmuster 
ist umständlich zuzuordnen. Besser wäre etwas wie 0x00 oder 0xff oder 
0xaa (=10101010) oder 0x55 (=01010101)

2cents schrieb:
> Schaltplan und Foto vom Aufbau wären durchaus hilfreich.
Ja, so ist das.

: Bearbeitet durch Moderator
von 2cents (Gast)


Lesenswert?

Lothar M. schrieb:
> Sieht nach falscher Baudrate aus.

Sieht nach statischem Pegel an der Rx-Leitung aus.

von Sebastian (Gast)


Lesenswert?

CKDIV8-Fuse im uC gesetzt? Falls der mit 1MHz statt mit 8MHz läuft dann 
sendet er mit 1200 Baud statt mit 9600 Baud. Kannst ja zur Prüfung im 
hterm mal 1200 einstellen ...

LG, Sebastian

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

2cents schrieb:
> Sieht nach statischem Pegel an der Rx-Leitung aus.
Warum erkennt dann der Empfänger im PC ein Startbit?
Denn ohne Startbit gäbe es ja kein empfangenes Zeichen...

von Sebastian R. (sebastian_r569)


Lesenswert?

Beliebter Fehler: Der AVR läuft mit internem Oszillator. Der ist ohne 
Nachjustierung aber meist zu ungenau, um im Baudratentoleranzbereich von 
PCs zu bleiben.

ALso: Externer Quarz angeschlossen und aktiviert?

von Falk B. (falk)


Lesenswert?

Lothar M. schrieb:
> 2cents schrieb:
>> Sieht nach statischem Pegel an der Rx-Leitung aus.
> Warum erkennt dann der Empfänger im PC ein Startbit?
> Denn ohne Startbit gäbe es ja kein empfangenes Zeichen...

Was erwartest du für 2cent an Kompetenz . . . ? ;-)

von Karl B. (gustav)


Angehängte Dateien:

Lesenswert?

Hi,
schau Dir das Terminalprogramm etwas näher an.
Mein "Leib-und-Magen-Terminal" möchte diese Einstellungen.
Teraterm oder auch Putty etc. pp.

(DCF77 - Uhr mit RS232 Terminal)

ciao
gustav

von Josia A. (Firma: Zumtobel) (josia)


Angehängte Dateien:

Lesenswert?

Danke für die antworten,

Habe die Taktrate falsch "eingestellt" (8Mhz) dacht es wäre von Werk aus 
auf 8Mhz eingestellt das ist stimmt aber nicht es ist 1Mhz...
Also habe das ganze auf 1 Mhz abgeändert. Nun blinkt eine LED bei einem 
Delay von 1s auch wirklich im sekundentakt.

die komischen Zeichen werden trotzdem noch gesendet.

TX,RX ist richtig angeschlossen, habe ich nochmal kontrolliert.

Es ist kein externen Quarz angeschlossen. Benutze im moment den internen 
1Mhz.

Schaltplan,Layout, Bilder von Aufbau sind im Anhang.

Als nächstens werde ich einen externen Oszilator anschließen fals ich 
zufällig einen habe. Im Beispielcode von mikrocontroller.net bekomme ich 
auch die Fehlermeldung das die Baudratefehler zu hoch ist...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Die GNDs des Mega und des UART-USB müssen verbunden sein.
Wenn alle Tipps hier nicht helfen, schadet es auch nicht, mal 2 Stopbits 
zu senden (USBS = 1), um dem Empfänger das Einrasten zu erleichtern.

von Falk B. (falk)


Lesenswert?

Josia A. schrieb:
> Es ist kein externen Quarz angeschlossen. Benutze im moment den internen
> 1Mhz.

Lies den Abschnitt und prüfe ALLE Punkte!

https://www.mikrocontroller.net/articles/AVR_Checkliste#UART/USART

> Als nächstens werde ich einen externen Oszilator anschließen fals ich
> zufällig einen habe. Im Beispielcode von mikrocontroller.net bekomme ich
> auch die Fehlermeldung das die Baudratefehler zu hoch ist...

AHA! Und was schließt du daraus?

Bei EXAKTEN 1MHz kann man keine 9600 Baud genau genug erzeugen, der 
Fehler liegt bei 8%. Nimm 8 MHz (CLK DIV Fuse deaktivieren) und gut. Es 
gibt keinen Grund, mit 1 MHz rumzugurken. Dann hat man weniger als 0,2% 
Fehler. Man muss natürlich auch das #define für F_CPU auf 8 MHz ändern.

Das 2. Problem ist dein interner RC-Oszillator, der den 8 Bzw. 1 MHz 
Takt generiert. Der ist nicht sonderlich genau. Das KANN funktionieren, 
muss es aber nicht. Steht alles oben im Artikel.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Josia A. schrieb:
> dacht es wäre von Werk aus auf 8Mhz eingestellt ...
> stimmt aber nicht es ist 1Mhz...
Ja, das steht so im Datenblatt.

> Als nächstens werde ich einen externen Oszilator anschließen
Ein Tipp: mach dort an die Versorgungspins vom µC noch einen 
Blockkondensator dran. Das steht auch im Datenblatt.

von Josia A. (Firma: Zumtobel) (josia)


Lesenswert?

Es Funktioniert!!! Ich bekomme nun die richtigen Werte auf meinem 
Terminal angezeigt.


danke nochmal für die weiteren hilfreichen antworten...


Also habe jetzt die richtige interne Frequenz eingestellt. Habe das noch 
nie vorher gemacht... Unser Lehrer hat uns beigebracht das man die 
Frequenz ändert indem man F_CPU im Programm schreibt.(Fuses nicht 
erwähnt...) Hätte auch früher selber drauf kommen aber jetzt weiß ich es 
ja!

Also Fazit: 1Mhz reicht nicht aus um eine genaue 9600 Baud rate zu 
erzeugen weil er dann einen Fehler von 8% hat.

Aber warum nicht? Wie kommt man auf die 8%?

von Falk B. (falk)


Lesenswert?

Josia A. schrieb:
> Aber warum nicht? Wie kommt man auf die 8%?

Rechnen? Die Formeln stehen im Datenblatt und auch im Quelltext!

von Christian E. (cerker)


Lesenswert?

Josia A. schrieb:
> Es Funktioniert!!! Ich bekomme nun die richtigen Werte auf meinem
> Terminal angezeigt.
>
>
> danke nochmal für die weiteren hilfreichen antworten...
>
>
> Also habe jetzt die richtige interne Frequenz eingestellt. Habe das noch
> nie vorher gemacht... Unser Lehrer hat uns beigebracht das man die
> Frequenz ändert indem man F_CPU im Programm schreibt.(Fuses nicht
> erwähnt...) Hätte auch früher selber drauf kommen aber jetzt weiß ich es
> ja!

Der macht auch sein Auto schneller indem er andere Zahlen auf den Tacho 
schreibt? ;)

Nein ernsthaft, die F_CPU Konstante ist dazu da, den verschiedenen 
Librarys die Taktfrequenz *bekannt*zumachen. Z.b. die Funktionen 
delay_ms und delay_us der avr-libc verwenden das.

> Also Fazit: 1Mhz reicht nicht aus um eine genaue 9600 Baud rate zu
> erzeugen weil er dann einen Fehler von 8% hat.
>
> Aber warum nicht? Wie kommt man auf die 8%?

Der U(S)ART im AVR benötigt die 16fache Baudrate als Taktfrequenz für 
die Baudrate. Bei 9600bps also 153600Hz. Das wäre von 1MHz aus ein 
Teilfaktor von 6.51041666667

Da der AVR aber keine PLL oder "Fractional Divider" hat kann man nur 
ganzzahlige Teiler der Taktfrequenz verwenden. Der nächste verwendbare 
Faktor ist also 7, das ergibt aber 142857.14 Hz, 7% unter 153600Hz (oder 
153600Hz ist 7.5~8% über 142857.14Hz).

Mit 2MHz klappt es schon, da kann man glatte 13 nehmen, welche 153846.15 
Hz ergeben, was völlig akzeptabel ist.

Wenn man alle Baudraten gut machen will, muss man einen Baudratenquarz 
verwenden, da gibt es z.B. 1,8432 MHz - 3,6864 MHz -  4,9152 MHz - 
6,1440 MHz - 7,3728 MHz - 9,8304 MHz - 11,0592 MHz - 12,2880 MHz - 
14,7456 MHz

All diese "krummen" Frequenzen zeichnen sich dadurch aus, dass sie für 
die üblichen Baudraten bis hoch zu 115200 bps einen ganzzahligen Teiler 
ergeben.

Gruß,
Christian

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Mit Double-Speed (U2X-Bit in UCSRA setzen und Faktor in der
Umrechnungsformel von 16 in 8 ändern) wird die Abweichung bei 9600 bd
stark reduziert. Trotzdem nimmt man bei UART-Anwendungen besser einen
Quarz, da der interne RC-Oszillator nicht besonders genau ist.

von S. Landolt (Gast)


Angehängte Dateien:

Lesenswert?

> Wie kommt man auf die 8%?

Steht z.B. im Datenblatt.

von Josia A. (Firma: Zumtobel) (josia)


Lesenswert?

Vielen Dank für deine ausführliche Antwort Christian,

habs jetzt gecheckt :D.



MfG
Josia

von Wolfgang (Gast)


Lesenswert?

Josia A. schrieb:
> Es ist kein externen Quarz angeschlossen. Benutze im moment den internen
> 1Mhz.

Im ATmega32 gibt es keinen internen Quarz.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Josia A. schrieb:
> Unser Lehrer hat uns beigebracht das man die
> Frequenz ändert indem man F_CPU im Programm schreibt.
Nein, F_CPU muss den Wert haben, die deine Hardware hat.
Sonst rechnen die Formeln falsche Registerwerte aus.

von Sebastian (Gast)


Lesenswert?

Josia A. schrieb:
> Unser Lehrer hat uns beigebracht das man die Frequenz ändert indem man
> F_CPU im Programm schreibt.(Fuses nicht erwähnt...)

Ein Kurs ohne Arduino sondern mit rohem IC auf eigener Platine. Wow!

LG, Sebastian

von Karl B. (gustav)


Lesenswert?

Sebastian schrieb:
> Ein Kurs ohne Arduino sondern mit rohem IC auf eigener Platine. Wow!

Und dann noch ohne echte COM1 am PC.
Und über USB.

ciao
gustav

von Dietrich L. (dietrichl)


Lesenswert?

Josia A. schrieb:
> Unser Lehrer hat uns beigebracht das man die
> Frequenz ändert indem man F_CPU im Programm schreibt.(Fuses nicht
> erwähnt...)

Dann hast da ja jetzt die Gelegenheit, das dem Lehrer beizubringen.

Wenn er gut ist, bedankt er sich. Wenn nicht, kann das riskant sein...

von M. K. (sylaina)


Lesenswert?

Josia A. schrieb:
> Es ist kein externen Quarz angeschlossen. Benutze im moment den internen
> 1Mhz.

Dann kalibrier den mal. Wie das mit "Boardmitteln" geht habe ich z.B. 
hier beschrieben: http://www.skie.info/?p=296

von funny (Gast)


Lesenswert?

M. K. schrieb:
> Wie das mit "Boardmitteln" geht habe ich z.B. hier beschrieben:

ROFL!

Mit einem UART einen Oszillator kalibrieren .... boooaahhh ...
was Besseres könnte mir ja nicht einfallen. Zumal ein UART ja so
arbeitet dass er möglichst fehlertolerant alles versucht richtig
zu empfangen. Stichwort Oversampling.

von Yalu X. (yalu) (Moderator)


Lesenswert?

funny schrieb:
> ROFL!
>
> Mit einem UART einen Oszillator kalibrieren .... boooaahhh ...
> was Besseres könnte mir ja nicht einfallen.

Ja, deine Ausdrucksweise legt das nahe ;-)

Auch ich finde die Idee ziemlich clever:

Er kalibriert des Oszillator zielgerichtet auf den vorgesehenen
Einsatzfall hin, indem er genau diesen Einsatzfall (nämlich die
UART-Kommunikation) als Optimierungskriterium verwendet. Als angenehmen
Nebeneffekt kommt er dabei sogar ohne spezielles Equipment (wie
Funktionsgenerator oder Frequenzzähler) aus.

von Rainer V. (a_zip)


Lesenswert?

Yalu X. schrieb:
> Auch ich finde die Idee ziemlich clever:

Ja, das i s t clever und ist offensichtlich lang nicht so naheliegend, 
wie ich gedacht habe. Mach' ich praktisch bei jedem Controller ohne 
Quarz, wenn ich die Schnittstelle brauche :-)
Gruß Rainer

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.