Hallo.
ich habe ein Problem mit der Uart Schittstelle des Attiny2313. Ich
möchte mit 4800 baud empfangen. es sind 8 datenbits und 1 stopbit
vorhanden.
Nach meiner Interpretation sollten nun nach 9*208,3µs (1875 µs) jeweils
ein Empfangsinterrupt ausgelöst werden. Dieser tritt allerdings erst
nach 2280 µs auf. Ich hoffe, das mir jmd weiterhelfen kann.
achja. der 2313 läuft mit 8 MHz. Clkdiv ist aktiv.
void UARTinit(void)
{
UBRRL= 12;
UBRRH = 0;
UCSRB = (1 << RXEN) | (1 << RXCIE);
UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
sei();
}
ISR(USART_RX_vect)
{
neu = UDR;
PINB = ( 1 << PB3); // LED zur Auswertung mit OSZI toggeln
}
----------------------
habe es auch über eine Polling-Variante versucht. dort das gleiche
Problem
void USART_Receive_Polling( void )
{
while ( !(UCSRA & (1 << RXC)) )
;
neu = UDR;
PINB = (1<<PB3);
}
Hi
>Nach meiner Interpretation sollten nun nach 9*208,3µs (1875 µs)
Startbit vergessen.
>Dieser tritt allerdings erst nach 2280 µs auf.
Wie festgestellt?
MfG Spess
Beim UART gibt es immer auch ein Start-Bit. Darum ist Deine Rechnung
schon mal falsch: Es müssten 10*208,3µs=2083µs sein.
Da sind dann Deine 2280 nicht mehr weit weg. Ohne externen Quarz kann es
ja auch noch eine beträchtliche Abweichung im Takt geben. Und die
Interrupt Routine braucht auch Taktzyklen.
spess53 schrieb:> Hi>>>Nach meiner Interpretation sollten nun nach 9*208,3µs (1875 µs)>> Startbit vergessen.>>>Dieser tritt allerdings erst nach 2280 µs auf.>> Wie festgestellt?>> MfG Spess
Mit nem OSZI an der LED, die in der ISR getoggelt wird.
Also die Daten kommen über einen GPS-Empfänger. Dieser sendet mit 4800
8N1. Ich habe allerdings nirgendwo gelesen, dass dieser ein Startbit
sendet.
Bin davon ausgegangen, dass das "Startbit" das erste Zeichen nach dem
Stopbit ist, also das erste Bit der Datenbits.
Senden GPS-Empfänger nun also 1 Startbit + 8 Datenbits + 1 Stopbit?
Micha schrieb:> Also die Daten kommen über einen GPS-Empfänger. Dieser sendet mit 4800> 8N1. Ich habe allerdings nirgendwo gelesen, dass dieser ein Startbit> sendet.
UART hat immer ein Startbit und 1 oder 2 Stoppbits. Die sind so
selbstverständlich, dass sie nicht extra erwähnt werden.
> Bin davon ausgegangen, dass das "Startbit" das erste Zeichen nach dem> Stopbit ist, also das erste Bit der Datenbits.
Und was ist, wenn die zu übertragenden Bits so sind, dass sich der
Daten-Pegel nicht vom Ruhepegel unterscheidet? Woher weiß der Empfänger
dann, dass jetzt die Übertragung beginnt.
> Senden GPS-Empfänger nun also 1 Startbit + 8 Datenbits + 1 Stopbit?
JEDE UART Übertragung hat IMMER Startbit + Stopbit. Ohne sie würde UART
nicht funktionieren. Der Sender kann sich nur aussuchen, ob er 1 oder 2
Stopp-Bits benutzen will um so dem Empfänger ein bischen Zeit zwischen
den Zeichen zu verschaffen. Aber vorhanden sind Start+Stop immer.
Die Frage war, ob das Startbit auch von den GPS-Empfängern gesendet
wird, da ich hierdrüber bisher nichts gefunden habe. Oder ob die einfach
nur die Datenbits rausprügeln.
Micha schrieb:> Die Frage war, ob das Startbit auch von den GPS-Empfängern gesendet> wird, da ich hierdrüber bisher nichts gefunden habe. Oder ob die einfach> nur die Datenbits rausprügeln.
Welchen Teil von "Bei einer UART ist ein Startbit zur Funktionsweise
immer notwendig" hast du nicht verstanden?
Dann verstehe ich nicht, warum folgender Code nichts bewirkt. Ein 'G'
sollte min. 5 mal die Sekunde durch "$GP..." hereinkommen. Aber die LED
toggelt nicht
ISR(USART_RX_vect)
{
cli();
neu = UDR;
if(neu == 0x47)
PINB = ( 1 << PB3); // LED zur Auswertung mit OSZI toggeln
sei();
}
Karl Heinz Buchegger schrieb:> Micha schrieb:>> Die Frage war, ob das Startbit auch von den GPS-Empfängern gesendet>> wird, da ich hierdrüber bisher nichts gefunden habe. Oder ob die einfach>> nur die Datenbits rausprügeln.>> Welchen Teil von "Bei einer UART ist ein Startbit zur Funktionsweise> immer notwendig" hast du nicht verstanden?
es ging um die allgemeine funktion wie meine gps-maus sendet. kann ja
sein, dass diese kein startbit sendet und es deswegen mit einer gps-maus
und uart nicht funktioniert
Micha schrieb:> Dann verstehe ich nicht, warum folgender Code nichts bewirkt.
Vielleicht deswegen, weil deine UART grundsätzlich nicht funktioniert,
weil es zb ein Baudratenproblem gibt?
Hast du mal deine UART unabhängig vom GPS zb mit einem PC getestet?
Der µC sendet und der PC empfängt. Dann siehst du gleich, ob das alles
funktioniert.
Micha schrieb:> Karl Heinz Buchegger schrieb:>> Micha schrieb:>>> Die Frage war, ob das Startbit auch von den GPS-Empfängern gesendet>>> wird, da ich hierdrüber bisher nichts gefunden habe. Oder ob die einfach>>> nur die Datenbits rausprügeln.>>>> Welchen Teil von "Bei einer UART ist ein Startbit zur Funktionsweise>> immer notwendig" hast du nicht verstanden?>>> es ging um die allgemeine funktion wie meine gps-maus sendet. kann ja> sein, dass diese kein startbit sendet und es deswegen mit einer gps-maus> und uart nicht funktioniert
Hör mal.
Entweder die hat eine UART, dann kommt auch ein Startbit.
Oder sie hat keine UART, dann kann sie machen was sie will.
Aber wenn das Teil eine UART hat, dann kommt da auch ein Startbit. Denn
UART ohne Startbit geht nicht.
Jetzt geschnallt?
Und nein. Der Hersteller der Maus wäre schön blöd, wenn er seinem Teile
eine serielle Schnittstelle verpassen würde, die anders funktioniert als
der Rest der Welt.
Nein, habe ich nicht getestet. werde ich gleich einmal machen, danke.
wenn dort das selbe problem auftritt, ist dann der µC defekt, oder liegt
es an der Initialisierung? Diese sollte ja eigentlich korrekt sein oder?
Micha schrieb:> Nein, habe ich nicht getestet. werde ich gleich einmal machen, danke.>> wenn dort das selbe problem auftritt, ist dann der µC defekt,
Geh mal nicht davon aus, dass irgendwas defekt ist.
Der Fehler sitzt normalerweise vorm Bildschirm.
Meistens taktet einfach nur der µC nicht mit der Frequenz mit der
eigentlich takten sollte, weil keiner die Fuses umgestellt hat, so dass
der externe Quarz nicht benutzt wird sondern der µC immer noch mit dem
internen Taktgeber auf ca 1Mhz läuft.
Hi
>wenn dort das selbe problem auftritt, ist dann der µC defekt, oder liegt>es an der Initialisierung? Diese sollte ja eigentlich korrekt sein oder?
Es liegt dann mit großer Sicherheit am Takt des ATTiny. Der interne
RC-Oszillator ist für UART recht ungeeignet.
MfG Spess
Bedenke bitte auch, dass deine GPS Maus ein wenig Zeit braucht, um das
neue Zeichen zu senden. Wenn die Senderoutine nicht per Ringpuffer
organisiert ist, vergehen schon einige Mikrosekunden, bis sie merkt,
dass der Sender leer gelaufen ist und sie ihn dann wieder gefüllt hat.
Die von dir gemessenen Abstände zwischen den Interrupts liegen durchaus
im üblichen Rahmen.
ok. dann werde ich es anstatt dem internen quarz mal mit einem externen
versuchen.
Habe nun öfters gelesen, dass man dazu einen Quarz nehmen sollte der
z.B. 3.6864 MHz besitzt anstatt einem 1 Mhz Quarz. Welche Vorteil bietet
mir das?
Micha schrieb:> ok. dann werde ich es anstatt dem internen quarz mal mit einem externen> versuchen.
Es gibt keinen 'internen Quarz'.
Der Tiny hat einen RC-Schwingkreis. Der schwingt mal mit 900Hz, mal mit
1.1Mhz. Wenn der unkalibiert einigermassen genau 1Mhz macht, dann ist
das Zufall.
> Habe nun öfters gelesen, dass man dazu einen Quarz nehmen sollte der> z.B. 3.6864 MHz besitzt anstatt einem 1 Mhz Quarz. Welche Vorteil bietet> mir das?
Das sich die Teilerfaktoren ganzzahlig auf die benötigten Baudraten
ausgehen.
aber wieso funktioniert der interne quarz so schlecht?
er ist bei 4800 baud mit einem fehler von 0,2% angegeben, was 83ps
entspricht. und das ist ja nicht wirklich viel, da er sich doch auch
jedes mal selbst synchronisiert.
Zwischen zwei Zeichen kann bei UART beliebig viel Zeit vergehen. Zwar
wird der Sender auf 1, 1.5 oder 2 Stop Bits konfiguriert, aber das ist
nur eine Mindest-Angabe.
Wenn der Sender nichts zu senden hat, bleibt die Leitung die ganze Zeit
lang auf dem Pegel des Stop-Bits. Ich finde, man müsste daher eher von
einem Stop-Signal sprechen, das eine variable Länge hat und wo man die
mindest-Länge konfigiguriert.
Wenn wir nun wissen, dass das Stop-Signal die gesamte Zeitspanne
zwischen Zwei Zeichen in Anspruch nimmt, und jedes Zeichen sowohl mit
High als auch mit Low beginnen kann, dann muss es logischerweise ein
Startsignal geben, dass sich eindeutig vom Stop Signal unterscheidet.
1
_
2
__..._______| XXXXXXXX_________..._____
3
4
aaaaaaaaaaaa bccccccccddddddddddddd
a=Stop-Signal (immer Low)
b=Start-Bit (immer High)
c=Daten-Bits (5-9 Stück, typischerweise 8)
d=Stop-Signal (mindestens 1 Bit lang)
Kleine Stolperfalle: Die Dauer des Stop-Signals muss nicht exakt ein
vielfaches von einem Bit sein. Jede beliebige Dauer ist zulässig. Darum
muss ein UART Empfänger imstande sein, seinen Bit-Takt bei jedem
Start-Bit erneut zu synchronisieren. Dazu wartet er auf die steigende
Flanke (zwischen a und b), wartet nochmal eine halbe Bitlänge ab lang
und liest dann die Datenbits (c) in regelmäßigen Zeitabständen ein.
Weicht die Bitrate von Sender und Empfänger zu weit voneinander ab, dann
wird das letzte Bit im falschen Moment eingelesen, man erhält dann
falsche Daten. Weicht die Bitrate noch mehr ab, tritt der Fehler schon
eher auf, dann sind also mehr Bits falsch.
Manche UART Schnittstellen synchronisieren ihren Takt bei jeder Flanke
auf der Rx Leitung. Ich meine mich zu erinnern, dass ein ATmega/ATtiny
das nicht kann.
Karl Heinz Buchegger schrieb:> Es gibt keinen 'internen Quarz'.> Der Tiny hat einen RC-Schwingkreis. Der schwingt mal mit 900Hz, mal mit> 1.1Mhz. Wenn der unkalibiert einigermassen genau 1Mhz macht, dann ist> das Zufall.
dann liegt es also hierdran, dass ca. 2300 µs und nicht 2083m µs
vergehen, bis ein neuer interrupt ausgelöst wird?
Es ist ein ganzzahliges vielfaches der gaengigen baudraten. Lass dich
aber von dem ganzen taktgerede nicht scheu machen. Meiner erfahrung nach
geht der interne rc oszi stabil bis zu einer baudrate von
38400(trial&error). Deine 4800 sind da weit darunter. Muss also woanders
haken.
Der interne Oszillator ist KEIN Quarz (wie bereits geschrieben). Laut
Datenblatt liegt er bis zu 10% daneben. Mit etwas Aufwand kannst du ihn
auf 2% Genauigkeit zerren.
Bei gesamt 10 Bit Zeichenlänge und einer Fehlermarge von 1/2 Bit hast du
5% Toleranz, bis es zuverlässig knallt. Dann muss aber der Sender schon
100% genau arbeiten. Wenn wir dem auch ein wenig Spielraum geben ...
Wenn etwas mehr zeit vergeht, kann das daran liegen, dass das GPS ding
idle-perioden zwischen den frames einfuegt. Diese koennen theoretisch
beliebig lang sein. UART is kein strikt taktsynchrones protokoll.
Sinnvollerweise soll der Poster das UART ein paar Zeichen senden lassen.
Dann laesst sich messen, wielange ein Bit wirklich ist. Resp ob die
Baudrate stimmt.
Habe den Mikrocontroller nun mit einem externen Quarz mit 3,6864 MHz
versehen. Der Takt ist nun stabil. Die ISR wird exakt alle 2280 µs
aufgerufen. Allerdings funktioniert das Auslesen des Datenregisters
einfach nicht richtig. Die LED soll dabei jedes mal toggeln, sobald das
Zeichen für einen neuen Datensatz empfangen wurde ($). Allerdings tut
sie es nicht^^)
hier nochmal der quellcode.
void UARTinit(void)
{
// 4800 8N1
UBRRL= 47;
UBRRH = 0;
UCSRB = (1 << RXEN) | (1 << RXCIE);
UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
sei();
}
ISR(USART_RX_vect)
{
neu = UDR;
if(neu == '$')
PINB = ( 1 << PB3); // LED zur Auswertung mit OSZI toggeln
}
Bei neueren AVRs kann man mit einer 1 die man auf das PIN Register
schreibt den PIN Toggeln lassen ! Ist also OK. Aber geht das auch beim
Attiny2313 ?
1. Hast du die Fuses richtig gesetzt ?
2. Hast du DDRB Pin 3 auf 1 gesetzt ?
Zeig mal deine Fuses und den gesammten Quellcode.
Hab es folgendermaßen vorher schon einmal getestet:
void PINinit(void)
{
DDRB = (1 << PB3);
}
void UARTinit(void)
{
// 4800 8N1
UBRRL= 47;
UBRRH = 0;
UCSRB = (1 << RXEN) | (1 << RXCIE);
UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
sei();
}
ISR(USART_RX_vect)
{
neu = UDR;
PINB |= ( 1 << PB3);
// if(neu == '$')
// PINB = ( 1 << PB3); // LED zur Auswertung mit OSZI toggeln
}
Hierdurch lasse ich mir halt anzeigen, dass gerade die ISR aufgerufen
wird. Dies habe ich mit dem OSZi überprüft und wie oben beschrieben
toggelt hier die LED alle 2300 µs. Was mich halt noch ein wenig
verwundert sind erstens die 2300 µs (anstatt von 2083 µs) und das
Fuses sind folgendermaßen:
SPIEN: Haken
BODLEVEL: disabled
SUT_CKSEL: EXTXOSC_3MHZ_8MHZ_14CK_4MS1
Sven schrieb:> ISR(USART_RX_vect)> {> neu = UDR;> PINB |= ( 1 << PB3);
Auch das ist kein Toggeln.
> wird. Dies habe ich mit dem OSZi überprüft und wie oben beschrieben> toggelt hier die LED alle 2300 µs. Was mich halt noch ein wenig> verwundert sind erstens die 2300 µs (anstatt von 2083 µs) und das
Tu dir endlich selbst einen Gefallen und verbinde deinen Tiny über die
UART mit dem PC und sieh endlich nach, was da wirklich passiert!
Da kannst noch 3 Wochen mit dem Oszi rumfuhrwerken, hängst du deinen
Tiny über einen MAX232 an den PC, stellst dort im Terminal 4800 Baud ein
und tippst drauf los, dann muss ein entsprechendes Echo Programm alles
was du tippst, zum Terminal zurückschicken. Tut es dass, dann weißt du,
das deine UART einwandfrei funktioniert. Tut es das nicht, dann weißt
du, dass sie nicht funktioniert, was wiederrum in den meisten Fällen an
einer falschen Baudrate (genauer am falschen Faktor) und da wiederrum
meistens an der falschen Taktfrequenz liegt. Das ist (wenn man einen MAX
hat) ein Test auf 10 Minuten und man weiß was Sache ist.
Du kannst noch wochenlang im Nebel stochern und nicht weiterkommen. Oder
du kannst einfach mal einen aussagekräftigen Test benutzen, der dir in
10 Minuten eindeutig bestätigt, ob deine UART funktioniert oder nicht.
Karl Heinz Buchegger schrieb:> Sven schrieb:>>> ISR(USART_RX_vect)>> {>> neu = UDR;>> PINB |= ( 1 << PB3);>> Auch das ist kein Toggeln.
Also meine LED toggelt durch diese Anweisung ;)
Auszug aus dem UM:
Toggling the Pin
Writing a logic one to PINxn toggles the value of PORTxn, independent on
the value of DDRxn.
Note that the SBI instruction can be used to toggle one single bit in a
port.
----------------------
Da ich keine Hardware hier habe kann ich es mit dem Max232 nicht testen.
Habe mir die von der GPS-Maus gesendeten Daten nun einmal genau
angeschaut und dabei einen ganzen Satz ausgewertet. Das Signal sieht
folgendermaßen aus:
1 Startbit (+5V)
8 Datenbits
1 Stopbit (0V)
evtl. ein 2.Stopbit oder ein Ruhepegel der Maus, aber ebenfalls 0V.
Hieraus erklären sich dann auch die knapp 2300 µs.
Allerdings fruchtet das Auslesen des UDR irgendiwe immer noch nicht zu
100%.
Im Anhang befindet sich der vollständige Code
Sven schrieb:> Habe mir die von der GPS-Maus gesendeten Daten nun einmal genau> angeschaut
Dann kannst Du auch die 8 Datenbits analysieren und sehen, was da
wirklich geschickt wird. Vielleicht ist es nicht das, was Du erwartest.
> Allerdings fruchtet das Auslesen des UDR irgendiwe immer noch nicht zu> 100%.
Was heißt das? Manchmal geht es?
Gruß Dietrich
Sven schrieb:> Karl Heinz Buchegger schrieb:>> Sven schrieb:>>>>> ISR(USART_RX_vect)>>> {>>> neu = UDR;>>> PINB |= ( 1 << PB3);>>>> Auch das ist kein Toggeln.>> Also meine LED toggelt durch diese Anweisung ;)
Ooop.s da steht ja PINB und nicht PORTB.
Da hab ich wohl gelesen, was ich lesen wollte.
Dietrich L. schrieb:> Sven schrieb:>> Allerdings fruchtet das Auslesen des UDR irgendiwe immer noch nicht zu>> 100%.>> Was heißt das? Manchmal geht es?>> Gruß Dietrich
Das soll bedeuten, dass das Auslesen prinzipiell funktioniert,
allerdings nicht das erwartete Ergebnis dabei herauskommt.
Habe festgestellt, dass wohl andauernd das Frame Error Bit gesetzt wird,
wenn die ISR aufgerufen wird.
> evtl. ein 2.Stopbit oder ein Ruhepegel der Maus, aber ebenfalls 0V.> Hieraus erklären sich dann auch die knapp 2300 µs.
Na dann konfigurier doch mal nen 2. Stop Bit.
habe ich schon ausprobiert. das war leider auch nicht die lösung des
problems.
muss das Startbit nicht normal einen Pegel von 0V und das Stopbit einen
von Vcc besitzen? Bei mir ist es nämlich genau andersherum
Uwe schrieb:> Na dann konfigurier doch mal nen 2. Stop Bit.
Aber als Empfänger brauchst Du das nicht. Es ist sogar besser, wenn der
Empfänger 1 Stopbit hat und der Sender 2. Dann werden bei lückenlosem
Senden Baudratenunterschiede eher verkraftet (Empfänger langsamer als
Sender)).
Gruß Dietrich
Uwe schrieb:>> evtl. ein 2.Stopbit oder ein Ruhepegel der Maus, aber ebenfalls 0V.>> Hieraus erklären sich dann auch die knapp 2300 µs.> Na dann konfigurier doch mal nen 2. Stop Bit.
Ist egal.
Die Anzahl der Stopp-Bits ist für den Sender relevant. Im Grunde macht
man damit nur eines: Man verschafft dem Empfänger ein wenig Zeit um das
gerade eben übertragene Zeichen verarbeiten zu können.
"Stopp Bit" ist eine hoch trabende Bezeichnung. Sieht man sich das ganz
mal auf Ebene der Logikpegel an, dann sieht man, dass das einfach nur
eine Pause zwischen dem letzten Datenbit und dem nächsten Startbit ist,
in der die Leitung auf Ruhepegel gehalten wird. D.h. Ist der Sender auf
2 Stoppbits und der Empfänger auf 1, dann passiert genau gar nichts
schlimmes. Denn ob der Sender jetzt 58 Stopbits macht oder nach 1
Stopbits eine kleine Pause in der Übertragung einlegt, kann der
EMpfänger nicht unterscheiden. Beides ist elektrisch auf der Leitung
identisch.
Sven schrieb:> habe ich schon ausprobiert. das war leider auch nicht die lösung des> problems.>>> muss das Startbit nicht normal einen Pegel von 0V und das Stopbit einen> von Vcc besitzen? Bei mir ist es nämlich genau andersherum
Du musst unterscheiden zwischen echter RS232 und der TTL Version.
echte RS232 benutzt Pegel von nominell -12V und +12V, währendf TTL sich
bei 0V und 5V abspielt. Die Pegelhübe sind genau anders rum. Bei TTL ist
0V der Ruhepgel, bei RS232 ist es +12V.
ok. also gibt der gpsempfänger die daten also im ttl-pegel heraus.
kann der 2313 denn diesen pegel verarbeiten oder benötigt er einen
anderen? denn aus dem datenblatt geht folgendes hervor
St Start bit, always low.
(n) Data bits (0 to 8).
P Parity bit. Can be odd or even.
Sp Stop bit, always high.
und das würde ja nicht passen, so dass ich die pegel genau umdrehen
müsste, wenn ich das jetzt richtig interpretiere
Sven schrieb:> muss das Startbit nicht normal einen Pegel von 0V und das Stopbit einen> von Vcc besitzen?
Ja!
> Bei mir ist es nämlich genau andersherum
Da brauchst Du wohl noch einen Inverter :-))
Als einfacher Test für die Polarität gilt auch: wenn nichts gesendet
wird (der Sender natürlich angeschlossen!), muss der Ruhepegel log. "1"
sein.
Gruß Dietrich
Hast du deine GPS-Maus eigentlich schon mal direkt an den PC
angeschlossen und mit einem Terminal-Programm nachgesehen, was die so
von sich gibt?
Wenn ja, wenn das also geklpaat hat, und die Ausgabe gut ausgehen hat,
dann brauchst du auf jeden Fall einen INverter, wenn du an den Tiny
gehst.