Forum: Mikrocontroller und Digitale Elektronik USART(ATmega32) zu COM(PC)


von Frank O (Gast)


Lesenswert?

Hallöchen,


mir ist aufgefallen das es ziemlich viele dieser Anfragen gibt bezügl. 
des USART/UART.

Ich habe ein Problem mit dem Kabel.
Habe mir aus Flachbandkabel und zwei Steckern. Der erste ist ein 
COM-Stecker(weibl.), der andere ein 10-Pin-Stecker(der Name fällt mir 
gerade nicht ein).

Ich habe den TXD Pin (über MAX232) an den COM-Pin2, den RXD-Pin an den 
COM-Pin3 und den GND-Pin an den COM-Pin5 angeschlossen.
Habe ich da schon einen fehler gemacht?

Des weiteren sieht mein Quellcode wie folgt aus:

UCSRA |= (1<<U2X);
UCSRB |= (1<<TXEN)|(1<<UCSZ2);
UCSRC |= 
(1<<URSEL)|(0<<UMSEL)|(1<<UPM1)|(0<<UPM0)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0 
)|(0<<UCPOL);
UBRRH = UBRR_VAL>>8; //UBRR Wird vorher bestimmt
UBRRL = UBRR_VAL;

while(1){
while (!(UCSRA & (1<<UDRE))) {}

    UDR = 'x';    //SENDEN eines einfachen x
}

im Hyperterminal von Windows habe ich folgende Einstellungen:
BAUD:9600
Datenbits:8 (UCSZ2:1:0 auf 1 gesetzt ==> 9-Bit gibts hier einen 
Konflikt??)
Parität:Gerade (UPM1:0 auf EVEN gestellt)
Stoppbits:2  (USBS auf 1)
Flusssteuerung: kein (was hat es damit auf sich??)


Mit freundlichem Gruß

Frank O

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Frank O wrote:

> Hallöchen,
> mir ist aufgefallen das es ziemlich viele dieser Anfragen gibt bezügl.
> des USART/UART.

Entsprechend viele Hilfe/Information bei Problemen mit UART und 
RS232 müsste unterwegs sein ;-)

> Ich habe ein Problem mit dem Kabel.
> Habe mir aus Flachbandkabel und zwei Steckern. Der erste ist ein
> COM-Stecker(weibl.), der andere ein 10-Pin-Stecker(der Name fällt mir
> gerade nicht ein).
> Ich habe den TXD Pin (über MAX232) an den COM-Pin2, den RXD-Pin an den
> COM-Pin3 und den GND-Pin an den COM-Pin5 angeschlossen.
> Habe ich da schon einen fehler gemacht?

Erstes Bild bei 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART so sollte es 
aussehen. Deine Beschreibung passt in etwa dazu, ausser, dass man nicht 
sieht, wie du den MAX232 in deiner Schaltung hast.

> Des weiteren sieht mein Quellcode wie folgt aus:
>
> UCSRA |= (1<<U2X);
> UCSRB |= (1<<TXEN)|(1<<UCSZ2);
> UCSRC |=
> (1<<URSEL)|(0<<UMSEL)|(1<<UPM1)|(0<<UPM0)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0 
)|(0<<UCPOL);
> UBRRH = UBRR_VAL>>8; //UBRR Wird vorher bestimmt
> UBRRL = UBRR_VAL;
>
> while(1){
> while (!(UCSRA & (1<<UDRE))) {}
>
>     UDR = 'x';    //SENDEN eines einfachen x
> }

Also das ist ein Codefetzen und kein eigenständiger Quellcode. Man 
kann es nicht testen, sondern nur die kryptischen Werte im Datenblatt 
nachlesen. U.a. sieht man im Codefetzen nicht, wie dein UBRR_VAL 
definiert bzw. vorher bestimmt wird. Ein Setzen von U2X ("Doublespeed 
UART an") muss bei der Berechnung von UBRR_VAL berücksichtigt werden.

Nützlich wären auch Infos darüber, wie du 9600 Baud bei welcher 
Taktrate (Taktquelle?, Fuses?, F_CPU?) eigentlich setzen willst. 
Näheres dazu in der 
http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART

> im Hyperterminal von Windows habe ich folgende Einstellungen:
> BAUD:9600
> Datenbits:8 (UCSZ2:1:0 auf 1 gesetzt ==> 9-Bit gibts hier einen
> Konflikt??)

Ja, gibt einen Konflikt. Wenn du auf dem PC 8 Datenbits hast und auf dem 
Atmega32 9, kann es nicht funktionieren. Ok wäre 8-Bits

UCSRB = (1<<TXEN)|(0<<UCSZ2);

> Parität:Gerade (UPM1:0 auf EVEN gestellt)
> Stoppbits:2  (USBS auf 1)

Kann gehen, wenn es auf beiden Seiten (AVR und PC) hleich ist. Obige 
Bits sehen OK aus.

> Flusssteuerung: kein (was hat es damit auf sich??)

S. Grundlagen im RS232 Artikel und bei Wikipedia 
http://de.wikipedia.org/wiki/RS232

von Peter Diener (Gast)


Lesenswert?

Hallo,

du brauchst einen Pegelwandler zwischen Mikrocontroller und PC!
z.B. Max232, wenn du mit 5 Volt versorgst. Die Ein/Ausgänge am MC haben 
5 Volt-Pegel, die RS-232 vom PC +/- 15 Volt.

Flusssteuerung bedeutet, dass einer dem anderen verbieten kann, zu 
senden, wenn er gerade beschäftigt ist und keine Daten entgegennehmen 
kann. Der ATMEGA32 hat keine Hardwareflussteuerung und du hast sie auch 
nicht angeschlossen (RTS/CTS), du stellst also "keine" ein.

Lass für die ersten Versuche die Parity weg, also 8 bit am MC und am 
Terminal einstellen. Also Parity: "keine".

Nimm, nach korrektur der Schaltung mit Max232 vorsichtshalber einen 
neuen Atmega, der könnte durch die 15 Volt zerstört worden sein. Wenns 
dann geht kannst du ja den alten ausprobieren.

Ich hoffe, das hilft etwas.

Grüße,

Peter

von Frank O (Gast)


Lesenswert?

Hey Danke,


das klappt jetzt, außerdem verwende ich das Bray-Terminal irgendwie ist 
das funktionaler.

Jetzt nur nochmal eine Frage zum Verständnis. Ich möchte ja den 
korrekten Wert/Buchstaben/String wie auch immer empfangen. Zum Testen 
sende ich immer ein großes X und bekomme aber mal ein B, H, oder ein 
Kästchen. Bei BrayTerminal steht zusätzlich, Frame Error da, das heißt 
ich weiß das irgendetwas Falsch läuft.


mfg Frank

von Peter Diener (Gast)


Lesenswert?

Hallo,

ein Frame-error bedeutet, dass entweder nicht die richtige Anzahl Bits 
empfangen worden ist, oder dass irgendeine andere Signalfoge (Start, 
Stopp) nicht stimmt. Das passiert üblicherweise, wenn man sich bei der 
Baudrate verrechnet hat.

Es wäre hilfreich, wenn du deine Schaltung zur Pegelwandlung kurz 
beschreiben oder posten könntest. Hier sollte man nicht sparen, dass die 
Pegel mit entsprechend starken und schnellen Treibern gesendet werden 
ist wichtig.

Grüße,

Peter

von Frank O (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,


ich verwende das RN-Control v1.4, aus dem "Roboternetz"(siehe Anhang 
Schaltplan).

Der MAX232 wandelt das automatisch, um die Schaltung musste ich mich 
also nicht kümmern.

Der Wert für das UBRR-Register beläuft sich laut Datenblatt auf 
103:BAUD9600 bei 16MHz und einfacher Übertragungsrate.

Ich hab nochmal "rumgeschraubt" am Quelltext, die Parity auf EVEN 
gestellt(gibt es da einen Vorteil ob EVEN oder ODD oder KEINE??), 
2STOPPBITS.

Fazit die Fehler der Übertragung werden weniger.

Ich möchte aber nochmal kurz den Fehler erläutern.
Wenn ich auf EMPFANGEN bzw. CONNECT klicke gibt es bei mir zwei 
Möglichkeiten, (a) nur FRAME ERRORS (b) das RICHTIGE ZEICHEN...

und je nachdem wie oft ich das CONNECT/DISCONNECT anklicke funktionierts 
oder nicht.

Hier nochmal der Quelltext:
//---------------------------------------------------------------------- 
---
//---------------------------------------------------------------------- 
---
#include <avr/io.h>

int UBRR_XX = 207; //baud 9600 DOPPELTE ÜBERTRAGUNGSRATE
//---------------------------------------------------------------------- 
---
//*** Testprogramm für den USART des ATMega32 ***//
//---------------------------------------------------------------------- 
---

int main(void){

UCSRA |= (1<<U2X);
UCSRB |= (1<<TXEN);
UCSRC |= 
(1<<URSEL)|(0<<UMSEL)|(1<<UPM1)|(0<<UPM0)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0 
)|(0<<UCPOL);
UBRRH = UBRR_XX>>8;
UBRRL = UBRR_XX;


while(1){

while (!(UCSRA & (1<<UDRE))) {} //Warten bis Senden möglich
    UDR = 'X';  //Senden eines X !

}

return 0;
}
//---------------------------------------------------------------------- 
---
//---------------------------------------------------------------------- 
---
Grüße

Frank

von Peter Diener (Gast)


Lesenswert?

Hallo,

mit 16 MHz Quarz an einem ATmega32 kann man keine RS-232 mit genormter 
Baudrate betrieben. Du brauchst dafür ein Baudratenquarz.
z.B. 14,7456 MHz

Und setz U2X nicht, das reduziert die Präzision im Empfänger.

Dann wird die Quarzfrequenz mit einem 16er Prescaler runtergeteilt, dann 
musst du nur noch z.B. 47 in UBRRL reinschreiben und bekommst 19200 
Baud.

Wie rechnet man das?

(QuarzFrequenz/16/Baudrate) - 1 = UBRR,

Was kommt da bei deinem Quarz raus (9600 Baud, 16 MHz):

16MHz/16/9600 = 104,1666666....   Dadurch kann man nicht ganzzahlig 
teilen!

Du hast also einen Baudratenfehler.

Jetzt rechnen wir das für U2X gesetzt:

16MHz/8/9600 = 208,333333.....  Du hast korrekt 1 weniger eingestellt, 
das ändert aber nichts daran, dass die Baudrate nicht 9600 ist, sondern:


16MHz/8/208 = 9615,38 Baud    Ob das funktiniert ist ein 
Zufallsexperiment.

So würde ich das einstellen:

UCSRA nicht anfassen.
UCSRB |= (1<<TXEN);

UCSRC |=
(1<<URSEL)|     muss gesetzt sein
(0<<UMSEL)|     Asynchrone Schnittstelle
(0<<UPM1)|      no parity
(0<<UPM0)|      no parity
(0<<USBS)|      one stop bit only
(1<<UCSZ1)|     8-bit mode
(1<<UCSZ0)|     8-bit mode
(0<<UCPOL);     Write this to zero in asynchronous mode

oder kürzer:

UCSRC = 0b10000110;

dann weiter:

UBRRH = 0;
UBRRL = 47;

Quarz 14,7456MHz einbauen, im Terminal 19200 Baud, 8 bit, no parity, one 
stop bit, no flow control einstellen und es muss funktionieren.

Viel Erfolg damit,

Peter

von Stefan K. (_sk_)


Lesenswert?

@Peter:
so genau muss die Baudrate auch wieder nicht stimmen, auf S.154 des 
ATmega32 Datasheet ist eine Tabelle des tolerierbaren Fehlers, in diesem 
Fall sind +/- 2% zulässig.

@Frank:

>Ich möchte aber nochmal kurz den Fehler erläutern.
>Wenn ich auf EMPFANGEN bzw. CONNECT klicke gibt es bei mir zwei
>Möglichkeiten, (a) nur FRAME ERRORS (b) das RICHTIGE ZEICHEN...
>
>und je nachdem wie oft ich das CONNECT/DISCONNECT anklicke funktionierts
>oder nicht.

Wunderbar, eine Fehlerbeschreibung (sieht man selten ...)!
(b) deutet darauf hin, dass Du gar kein Problem hast!
Du lässt den ATmega rennen, und drückst dann CONNECT, richtig?
In diesem Fall versucht sich die PC-Schnittstelle auf die bereits 
laufende Datenübertragung des Atmel zu synchronisieren. Und das klappt 
nur manchmal. Beide UARTs müssen synchron zueinander laufen, und dazu 
brauchen sie (beim Start) eine kurze Pause.

Die einfachste Lösung ist, in die Übertragung des ATmega ab und an ein 
kurzes Delay (länger als ein Frame, bei 9600 baud also  > 1ms) 
einzubauen.

Viele Grüße, Stefan

von Frank O (Gast)


Lesenswert?

Hallo,

mhh die Idee einen genauen Quarz zu nehmen find ich nicht schlecht, 
passt mir aber leider nicht, weil ich die 16MHz schon brauche, für 
zeitkritische Messungen.


Das mit dem Connect und ATMega32 läuft bereits dachte ich mir auch 
schon, habs auch verändert.

1.Frage: Was bringt mir das EVEN/ODD Parity-Bit?(Datenblatt werde ich 
gleich nochmal genauer Lesen!)

2.Frage: Warum empfiehlt sich ein einzelnes Stoppbit?


Grüße Frank

von Peter Diener (Gast)


Lesenswert?

Hallo,

es ist schon richtig, dass die Baudrate einen leichten Fehler haben 
darf.
Wenn aber Fehler auftreten, sollte man es mal mit der korrekten 
versuchen.

Das Parity Bit ist ein Prüfbit, das jedem Byte hinzugefügt wird, wenn 
Parity benutzt wird. Even Parity bedeutet, dass mit dem Prüfbit die 
Anzahl "Einser" des Bytes und des Prüfbits zusammen auf eine gerade 
(even) Anzahl ergänzt wird. Odd ist entsprechend ungerade.

Daran kann ein Übertragungsfehler erkannt werden, er muss aber nicht 
zwingend erkannt werden, es kann auch sein, dass Fehler nicht erkannt 
werden, wenn z.B. zwei Bits falsch sind.

Beispiel:

übertrage 0b10001010
Das hat drei Einser.
Wenn die Parity even ist, wird ein weiterer Einser als Parity angehängt.
Wenn sie odd ist, wird eine Null angehängt.
Der Empfänger weiß dann, dass die Anzahl an Einsern im Nutzbyte ungerade 
war. Wenn das nicht stimmt, liegt auf jeden Fall ein Fehler vor.

Für deine Versuche ist es wichtig, dass die Übertragung an sich 
funktioniert, lass deshalb die Fehlererkennung über parity abgeschaltet, 
sonst siehst du deine Fehler nicht, sie werden einfach ignoriert.

Ich würde zudem eine Pause von einer Sekunde zwischen dem Senden der 
Bytes einbauen, das Hilft dem PC bei der Synchronisation und dir hilft 
es, zu erkennen, ob bytes verloren gehen.

Das Verwenden von zwei Stoppbits ist unüblich, eine gängige Betriebsart 
zur Inbetriebnahme von seriellen Schnittstellen ist 8N1:
8 bits, no parity, 1 stop bit.

Viele Grüße,

Peter

von Peter B. (basejump)


Lesenswert?

Bray-Terminal

//---------------------------------------------------------------------- 
---

http://braypp.googlepages.com/terminal

von Peter Diener (Gast)


Lesenswert?

Hallo,

wenn dir das Quarz mit 14,7456MHz zu langsam ist, kannst du auch eins 
mit 15,9744MHz verwenden.
UBRRL ist dann auf 51 zu setzen für 19200 Baud.

Als reines Bedienterminal eignet sich auch Putty hervorragend.
Hat aber keine zusätliche Anzeige von Statussignalen oder 
HEX-Übersetzer...
ist nur für ASCII gedacht.

Wenn du was gescheites suchst, probier Realterm:
http://realterm.sourceforge.net/

Viel Erfolg,

Peter

von Frank O (Gast)


Lesenswert?

Hallöchen,


habe keinen Überblick über sämtliche Mikrocontroller.
Dazu muss ich sagen, ich benutze den ATmega32 als Ereigniszähler, über 
den ICP-Pin (TIMER/COUNTER1 16-Bit zähler), genauer gesagt ich Messe 
Pulsbreiten.

Nun die Frage, was ist derzeit das Maximum an Geschwindigkeit(in MHz :)) 
??
Und um welchen Controller würde es sich dann handeln, da mir 16MHz eine 
Genauigkeit von etwa 4us geben, ich brauchs genauer. Nanosekunden oder 
kleiner wäre super genial!!


Grüße Frank

PS: Danke für die bisher sehr ausführlichen Tips!

von Peter Diener (Gast)


Lesenswert?

Hallo,

Nonosekunden sind natürlich ein Wort. Was willst du damit machen?

Also eine konventionelle Technologie hat eine Auflösung von 
1/Taktfrequenz.
1 Nanosekunde entspricht dann einer Frequenz von 1 GHz.

Ich glaube die schnellsten AVR Mikrocontroller haben 24 MHz. Mit einem 
ARM kommst du vielleicht auf 80 MHz, darüber sind dann eigentlich alle 
in nicht mehr handhabbaren Gehäuseformen (BGA).

Ich würde aber eher versuchen, es irgendwie zu umgehen, eine Pulsbreite 
auf 1 Nanosekunde genau messen zu müssen.

Ansonsten gibt es schon Ansätze, die das können. Es gibt 
Phase-locked-loops, die mit mehreren phasenverschobenen Takten und 
Zählern auch mit niedrigerer Taktfrequenz eine so hohe Auflösung 
erreichen können. So was setzt man z.B. in Laserabstandsmessgeräten ein.

Einige der TMS320C2000 DSPs von TI können Pulsweiten mit einer Auflösung 
von 150 ps(!) ausgeben, vielleicht sind da welche dabei, die auch Pulse 
messen können, müsstest du nachschauen. Oder viellecht kann man mit 
einem so generierten Referenzpuls die eingehenden Pulse abschätzen.

Wenn es nur ein Versuchsaufbau ist, würde ich einfach ein Speicheroszi 
verwenden. Tektronix hat dafür die praktische Trigger hold off Funktion, 
damit kann man auch von sehr langen Pulsen sehr ganau die Länge 
bestimmen (auf wenige Nanosekunden genau).

Viele Grüße,

Peter

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.