UART einzelne Zeichen senden

(Firma: Zumtobel) #6904368
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
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #6904389
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.
(Firma: Zumtobel) #6904438
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...
Angehängte Dateien:
#6904452
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.
(Firma: Zumtobel) #6904474
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%?
#6904499
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
Moderator #6904509
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.
Gast #6905898
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.
Moderator #6906524
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.

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