Asynchrone Datenübertragung mit PIC16F690

Hallo,

ich habe es bisher nicht geschafft, mit dem EUSART-Feature des PIC16F690 asynchron Daten zu senden. Kann der Misserfolg daran liegen, dass während der Übertragung alle Interrupts disabled sein müssen? Ich befürchte das fast, habe das aber bisher in den Datasheets nicht gefunden. Hat vielleicht hier jemand Erfahrung damit? Ich würde mich über aufklärende Hinweise freuen.

Viele Grüße von Ph33

was geht denn nicht?
Hallo Ph33,

was geht denn nicht?

  • kommt garnichts raus? Wie ist der Pegel des TX?
  • kommt ein falsches Signal raus? --> Baudrate, intertierung, Parity …
  • hast Du ein einfaches Beispiel nach Datenblatt versucht und ein Oszi dran?
  • geht vielleicht nur ein Zeichen aber bricht danach ab?
  • hast Du vielleicht Parity und 8 Bit?
  • was ist mit dem Emfang?

Gruß
achim

Und nein, ich kenne keinen PIC, in dem während einer Übertragung interrupts disabled sein müssten. Das würde technisch keinen Sinn ergeben, da es dann auch per SW ginge. (O.T. das IC in PIC steht ja ursprünglich für Interrupt-Controller :wink:

Hallo Achim,
danke für Deine Antwort. Ich will kurz beschreiben, was ich tue.
Ich betreibe 2 PIC16F690 in einem Gerät.In PIC2 wird der Takt erzeugt (Quarz), und OscOUT habe ich direkt mit OscIN des PIC1 verbunden. Die Taktsignale an beiden PICs sehen gut aus. Du hattest mir vor einigen Wochen empfohlen, einen Treiber zwischenzu-
schalten; das ist aber offenbar nicht nötig.
In PIC1 werden 5 analoge Signale (Temperaturmessungen mit NTC-Widerständen) digitalisiert. Diese 5 Werte (=5 Bytes) will ich immer mal wieder zu PIC2 übertragen, wo sie mit 7-Segment-Anzeigen dargestellt werden.
Ich habe die einzelnen Übertragungs-Schritte in EUSART nicht mit dem Oszillografen verfolgt, nur das, was in PIC2 dargestellt wurde, hatte keinerlei Beziehung zu den 5 Spannungen, die ich mit Potis simuliert habe.
Ich habe dann eine andere Übertragungsart gewählt: Bei jedem TIMER0-Interrupt in PIC1
(125 pro sek, dient als Uhr) wird in PIC2 ein Interrupt-on-change erzeugt und dann auf einen zweiten PORT ein Bit von den 5*8=40 Bits übertragen. Da die PICS gleichzeitig eingeschaltet werden, funktioniert das recht gut. Manchmal (sporadisch) geraten
die beiden PICs aus dem Takt und dieser Synchronismus ist gestört. Nach Power off-Power on, geht es wieder. Immerhin konnte ich mit dieser Methode zeigen, dass alle anderen Funktionen richtig laufen. Aber wohl ist mir bei dieser Übertragungsmethode nicht!
Ich möchte daher nochmal einen Versuch mit EUSART asynchron machen. Mit den Ergebnissen möchte ich gerne nochmal bei Dir anklopfen.
Ich habe in beiden PICs eine Baudrate von 9615 bit/sek eingestellt und beide nach Vorschrift konfiguriert. Womit ich allerdings überhaupt nichts anfangen kann, ist „Receive framing error“ und „Receive overrun error“. Ich weiß nicht, wieso diese Fehler auftreten können und was ich im Fehlerfall tun soll.
Ich melde mich!
Viele Grüße von Ph33

Hallo Ph33,

Womit ich
allerdings überhaupt nichts anfangen kann, ist „Receive
framing error“ und „Receive overrun error“.

Framing Error:
Die Async-Übertragung besteht aus Start-Bit, den Daten, Parity- und Stop-Bit.
Welche genau und wie verwendet werden bestimmst du beim Initialisieren.

Stimmt da etwas nicht, z.B. du sendest nur 1 Stop-Bit, sollten aber 2 sein, bekommst du diesen Fehler.

Du kannst die Daten nur wegwerfen.

overrun error
Im Prinzip können die Daten kontinuierlich gesendet werden.
Das UART stellt die Bits dann zuerst in einem Schieberegister zusammen und wenn ein Datum empfangen wurde, werden die Bits in ein Register kopiert und das nächste Datum wird empfangen.
Bis da nächste Datum fertig empfangen ist, hast du Zeit das Register auszulesen.
Machst du das nicht rechtzeitig, geht ein Datum verloren, was durch einen overrun error angezeigt wird.

Je nachdem musst du, bei obigen, Fehlern erst quittieren, damit das UART weiter arbeitet. Ich habe jetzt nicht im Datenblatt nachgelesen wie sich dein PIC da verhält.

MfG Peter(TOO)

Hallo Ph33

Neben den Hinweisen von Peter noch weitere Erfahrung

Eine erfolgreiche Kommunikation braucht dutzende korrekte Einstellungen. Ein paar fallen bei Dir weg, da z.B. Baudratenfehler auf beiden Seiten sich ausgleichen. Dennoch solltest Du so viele Einzelergebnisse überprüfen wie es gehl.

  1. Ein kontinuierlich sendender Uart mit 9.6kBaud erzeugt 8 * mehr interrupts als Dein bisheriges Verfahren. Je nach Compiler, Takt und Code kann das schon zuviel sein.
    –> am besten immer nur 1 Byte pro bisherigem Timerinterrupt senden, nicht „back to back“.

  2. Einen Datenstrom richtig anzufangen und zu beenden hat viele Pitfalls
    –> erstmal jeweils nur das gleiche Byte senden, z.B. 0xC0. ohne Parity
    –> auf der Empfangsseite dieses Zeichen jeweils ausgeben. Empfängst Du hier ein falsches Zeichen, kann man Buadratenfehler meist daran „errechnen“.

  3. Ggf. Zähler für die Interrupts einbauen und hochzählen. Du hast ja auf der empfangsseite eine Ausgabe (die 7-Seg-Anzeige).

Wenn das alles Problemlos läuft, dann ist die eigentliche Kommunikation schonmal in Ordnung. Der nächste Level läuft meist schneller, verursacht aber vertraktere Probleme.

Viel Erfolg
achim

Hallo Wilbert und Peter(TOO),
dank Eurer Hilfe ist es mir jetzt gelungen, die asynchrone DÜ mit EUSART zwischen 2 PIC16F690 zu realisieren. Besonders der Tipp von Wilbert, die Sache mit dem Oszillografen anzuschauen, hal mir sehr viel gebracht. Es ist etwas Anderes, wenn man sieht, was sich abspielt, als wenn man das nur liest. Der größte Fehler bei meinem Versuchsaufbau war wohl, dass (ich verhülle mein Haupt) die Baudraten in Sender und Empfänger verschieden eingestellt waren. Außerdem hatte ich an einer Stelle MOVFW statt MOVWF geschrieben. Finde mal so einen Fehler!
Ich übertrage jetzt bei jedem TIMER0-Interrupt (125/sek) zwei Bytes: die Nummer der Messstelle und den digitalisierten Wert. Dadurch korrigieren sich evtl. Übertragungsfehler selbst. Ich kann mir zwar immer noch nicht vorstellen, wie z.B. „Frameerror“ oder „Overrunerror“ zustandekommen sollen; mein Übertragungsweg ist eine massive Leiterbahn! Deswegen frage ich diese Errorflags nicht ab. Vielleicht später mal, wenn ich reingefallen bin.
Nochmal vielen Dank Euch beiden!
Viele Grüße von Ph33

Hallo Wilbert,
ich hatte schon geantwortet, ganz oben…
Grüße von Ph33

Hallo Peter(TOO),
ich hatte schon geantwortet, ganz oben…
Grüße von Ph33

Overrun
Hallo Ph33

Overrun kommt dann zustande, wenn Du bei Ankunft des ersten Zeichens noch mehr als 1ms(@9600) in einem Interrupt (oder Interrupt-Disabled) zubringst. Oft passiert das dann nur sehr selten und sorgt so Verblüffung oder Aberglauben (http://de.wikipedia.org/wiki/Nichtdeterministisches_…)

Gruß
achim

1 Like

Hallo Achim,

danke für Deine Erläuterungen. Ich arbeite mit Interrupt; in der ISR werden nur STATUS und Akku-Register gerettet, dann wird das erste Zeichen geholt. Es vergehen also nur ein paar µsek.
Deine Bemerkung bzgl. Aberglauben fand ich lustig! Man vermutet ja alles Mögliche, wenn etwas Unverständliches passiert, bis man den Fehler gefunden hat. Ich bin jetzt nicht der Superfreak, aber ich werde immer besser, auch dank Eurer Hilfe.Ich staune immer wieder über diese kleinen PICs, aber zum Aberglauben haben sie es bei mir noch nicht gebracht!
Viele Grüße von Ph33
(Ph soll an Physiker erinnern)

Hallo Ph33,

Ich übertrage jetzt bei jedem TIMER0-Interrupt (125/sek) zwei
Bytes: die Nummer der Messstelle und den digitalisierten Wert.
Dadurch korrigieren sich evtl. Übertragungsfehler selbst. Ich
kann mir zwar immer noch nicht vorstellen, wie z.B.
„Frameerror“ oder „Overrunerror“ zustandekommen sollen; mein
Übertragungsweg ist eine massive Leiterbahn! Deswegen frage
ich diese Errorflags nicht ab. Vielleicht später mal, wenn ich
reingefallen bin.

Tja, genau das macht den Unterschied zwischen Bastellösung und stabilem professionellem Programm!

Es kann immer zu einem Bitfehler kommen, sei es durch Störungen in der Speisung oder über HF, weil einer sein Handy neben deine Elektronik legt oder der Blitz in de Nähe einschlägt.
Es kann Betazerfälle im Gehäusematerial geben, kosmische Strahlung und wenns der Teufel will, regiert genau in deinem Chip ein Meson mit einem der Atomkerne.
Je kleiner di Chipstrukturen werden, umso kleiner wird ach die nötige Energie um ein Bit umzuwerfen.
Und wegen Betazerfall: Anfangs gab es DRAM nur im Keramikgehäuse. Beim Epoxy hatte man damals die Verunreinigungen noch nicht im Griff und DRAM wurde durch die Betazerfälle zu unzuverlässig.

Und wie ich dir geschrieben habe, kann ein UART nach einem Fehler, seine weiter Zusammenarbeit blockieren, bis der Fehler quittiert wurde. Dein Gerät läuft dann erst nach einem Neustart weiter, wenn du die entsprechende Fehlerbehandlung einsparst. Meistens ist so etwas dann die Ursache, wieso sich in Gerät 1x im Monat aufhängt.

Im einfachsten Fall, quittiert man die Fehlermeldung einfach und wirft das gestört empfange Zeichen einfach weg.

Dies bedingt aber wiederum eine andere Technik: Plausibilitätsprüfung.
Du sendest jetzt immer 2 Byte. Der Empfänge muss irgendwie erkennen können, welche 2 Bytes zusammen ein Pärchen bilden, als er muss sich wieder synchronisieren können, wenn mal ein Byte verloren geht.

Grundsätzlich sollte man alles was irgendwie von Aussen kommt auf gültige Wertebereiche testen und andernfalls entsprechend reagieren.
Gute Software macht dies auch an Modulgrenzen, man weiss nie ob nicht ein doofer Programmierer einen falschen Aufruf macht! :wink:

Oft funktionieren Berechnungen nur für einen bestimmten Wertebereich, ausserhalb gibt es Unter- oder Überläufe und die Ariane stürzt ab!
http://www4.in.tum.de/lehre/seminare/ps/WS0203/desas…

Hier noch ein paar weitere Müsterchen:
http://www.xing.com/net/qmsoftware/softwarefehler-ko…
http://www5.in.tum.de/~huckle/bugs.html

MfG Peter(TOO)