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
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
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
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
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
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
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
@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
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
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
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
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!
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