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.
Hi >Die Frage war, ob das Startbit auch von den GPS-Empfängern gesendet >wird, Ja. Sonst funktioniert das Ganze nicht. MfG Spess
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?
Hi
>Welche Vorteil bietet mir das?
Das sind Bauraten-Quarze. Bei denen wird bei üblichen Baudraten der
rechnerische Fehler gleich Null.
MfG Spess
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 }
Dort sollte eigentlich PINB |= (1 << PB3) stehen. Aber das bringt auch nicht die Lösung des Problems.
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
und zweitens, dass die anzeige eines zeichens (habe belieb viele zeichen gestetet) nicht funktioniert
Erst UBRRH und danach UBRRL schreiben. Aber obs das ist. Kompletter code. nicht bruchstücke.
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.
Es funktioniert nun. Lag wohl an den Pegeln. Nach Einbau eines Transistors + 2 Widerstände zur Invertierung passt alles. Danke für die Mühe
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.