PIC16: Probleme mit UART-Empfang

Ich habe einen PIC16 , für den die (asynchrone) UART-Übertragung einwandfrei funktioniert, aber der UART-Empfang erzeugt ungültige Ergebnisse.

Wird beispielsweise aals interpretiert O, bwird als interpretiert 'und cwird als interpretiert N.

Hier ist meine Empfangsfunktion:

char UART_read(void) {
    while(!PIR1bits.RCIF) {}

    return RCREG;
}

Meine Hypothese ist, dass die UART-Polarität für den Empfänger falsch ist, sodass insbesondere die Start-/Stoppbits durcheinander geraten. Ich habe das SCKPBit gesetzt (siehe Seite 302), um die Daten auf dem TX/CK-Pin zu invertieren, aber ich kann kein Äquivalent für den RX/DT-Pin finden.

Was könnte die Ursache dafür sein, dass der UART-Empfang nicht funktioniert? Wie kann ich die Daten auf dem RX/DT-Pin invertieren?

Was ist die Datenquelle? Sind Sie sicher, dass Quelle und Senke die gleiche Baudrate, Stoppbits, Parität, Spannungspegel usw. haben?
Was passiert auch, wenn Sie einen Loopback-Test durchführen?
Ähnliches ist mir aufgefallen, wenn die Baudrate nicht richtig mit der Frequenz des internen Oszillators übereinstimmt. OSCCONbits.IRCFRegister richtig konfiguriert?

Antworten (2)

BEARBEITEN : Diese Antwort wurde geändert, um den Kommentar des Fragestellers widerzuspiegeln, und weist darauf hin, dass er mit seiner Diagnose des Problems recht hat, was keine besonders nützliche Information ist. Die einzige nützliche Information in diesem Abschnitt ist die Tatsache, dass es kein Empfangs-Invert-Bit gibt ... Aber vielleicht hilft es zukünftigen Leuten, ihre eigenen UART-Probleme zu diagnostizieren


Also lasst uns einen Blick darauf werfen

a wird auf O abgebildet, was bedeutet, dass 01100001 auf 01001111 abgebildet wird

b wird auf ' abgebildet, was bedeutet, dass 01100010 auf 00100111 abgebildet wird

Nehmen wir an, dass vor jedem davon eine implizite 1 und danach eine implizite 0 steht (Start- und Stoppbits). Das RX-Modul empfängt ein kontinuierliches Low-Signal, dann wird das Stoppbit als High gesendet, das als Leerlaufsignal gefressen wird, dann wird die anfängliche 0 als Stoppbit konsumiert. Dann werden die restlichen Bits invertiert,

so 'a' == 1 10000110 0 initially (we send least significant bit first)
1 (implicit start bit) and starting 1 are both consumed as idle bits
then the first 0 is treated as a start bit
so received == 00001100 inverted (the extra zeros are the stop bit and idle bits after transmission has ended)
11110011 and reverse it (it was sent LSB first)
11001111 is what the inverted input would look like
01001111 is what's actually received which is super close!
if what you actually sent was "abc" all in a row, then the start bit of the b would make what was received 01001111 which matches exactly

'b' == 1 01000110 0 ==> 10001100 inverted and reversed gives
11001110 is what should have "logically" happened
00100111 actual
So that doesn't quite match, but if we assume that the "abc" is what happened again, we get
01001110 which is close enough (not sure where the shift came from)

Sieht so aus, als hätten Sie die Diagnose getroffen, leider gibt es im Empfänger auf dem PIC kein ähnliches Konfigurationsbit "Signal invertieren". Allerdings ist es nicht schwer, einen Inverter in den Empfangspfad zu legen, was ich übrigens empfehlen würde!

Wie Olin feststellte, reichen Standard-RS-232-Signale von +3 V bis +15 V für eine logische „1“ und von –3 V bis –15 V für eine logische „0“. Der PIC ist für den Betrieb mit "TTL" -Pegeln ausgelegt, was "Transistor-Transistor-Logik" bedeutet. Die Idee ist, dass der PIC so ausgelegt ist, dass er mit anderen Dingen kommuniziert, die sich physisch in der Nähe befinden (dh auf derselben Platine), und daher die zusätzliche Übertragungsentfernung und Rauschunterdrückung durch die vollen RS-232-Pegel für den "Standard" -Betrieb nicht benötigt werden. Es ist nicht praktikabel, die für den RS-232-Betrieb erforderlichen positiven / negativen Spannungen vollständig intern auf dem PIC zu erzeugen, daher war eine "normale" RS-232-Kommunikation nie wirklich eine Option.

Da TTL-Pegel nicht der Standard sind, sondern ein Derivat des Standards (gleiches Protokoll für Timing, Start- und Stoppbits, Parität, aber unterschiedliche Spannungen), kaufen Sie keinen Verbraucher-RS-232-Adapter für Ihren Computer, es sei denn, es hält sich an die Norm. Sie stellen RS-232-Adapter auf TTL-Ebene her und sind auf Bastler-Websites sehr beliebt! Schauen Sie sich das Kabel von Adafruit oder den Sparkfun FTDI Breakout an . Ich finde, dass es sich im Allgemeinen um einen RS-232-Level-Adapter handelt, wenn es sich um einen DB9-Anschluss handelt.

Das ist ein O(der Buchstabe), nicht eine 0(die Zahl). Also 01100001wird , 01100010, 01100011auf 01001111, 00100111abgebildet 01001110. Denken Sie auch daran, dass Bits zuerst LSB gesendet werden. Wenn also die Empfangsleitung invertiert ist, ist das Startbit ganz rechts . 1So 01100001wird ~10110000, 01100010wird ~11011000und 01100010wird ~10100111, alles passend zu dem, was ich empfange.
@Randomblue: Ich habe meine Antwort korrigiert, um die Analyse tatsächlich richtig durchzuführen, und einige zusätzliche Hinweise zur RS-232- und TTL-Diskrepanz für die PIC-Computer-Interaktion hinzugefügt.
Keines der beiden Produkte, die Sie verknüpft haben, um Logikpegelsignale in RS-232 umzuwandeln. Beide scheinen USB-Seriell-Konverter zu sein, was hier nicht zutrifft.
@OlinLathrop: Ich war mir nie ganz sicher, wie das eigentliche Protokoll hieß. "Serial" impliziert jedes nicht-parallele Kommunikationsprotokoll, und "Asynchronous Serial Protocol" scheint alle möglichen unterschiedlichen Zeichenrahmenmethoden, Endianness usw. zuzulassen. Sie haben Recht, dass die Links, die ich angegeben habe, nicht explizit auf rs -232 Adapter. Ist USB zu UART der richtige Begriff? Das Adafruit-Kabel nennt sich eigentlich ein "USB FTDI TTL-232-Kabel", weshalb ich annahm, dass "TTL-Pegel-RS-232-Adapter" ein angemessener Titel sei.
@OlinLathrop: Was ihre Anwendbarkeit auf diese Konversation betrifft, gebe ich zu, dass ich hier eine Annahme über die Verwendung von Randomblue getroffen habe. Er sagte, dass er versuche, seinen Windows 7-Computer mit seinem Projekt zu verbinden (im Kommentar unter deiner Antwort), und ich habe Links zu Produkten gegeben, die ihm das erleichtern werden. Er könnte max232-Schaltungen verwenden, um den Chip, den er jetzt hat, mit dem seriellen Adapter zu verbinden, den er jetzt hat, aber ich nehme an, dass er, wie die meisten Bastler, das schnell ermüdend findet und eine einfachere Methode wünscht.

Um zu sehen, ob Sie eine Inversion benötigen, sehen Sie sich den Leerlaufpegel der Leitung an. Normaler Logikpegel UART signalisiert Leerlauf hoch. Da Sie den Ausgang invertiert haben, sollte er im Leerlauf niedrig sein. Wenn das andere Gerät invertierte Signale zum Empfangen verwendet (Ihre Übertragung), verwendet es mit ziemlicher Sicherheit die gleichen Pegel für seine Übertragungen (Ihren Empfang). Überprüfen Sie mit einem Oszilloskop, aber Sie benötigen wahrscheinlich eine Inversion, die mit einem Inverter-Logikgatter oder nur einem Transistor und einem oder zwei Widerständen angesichts der niedrigen Datenrate erfolgen kann.

Wie hätten Sie jemals gedacht, dass der Empfang ohne Inversion funktionieren würde, wenn die Übertragung dies erforderte!?

Hinzugefügt:

Sie haben jetzt offenbart, dass Sie einfach die PIC-UART-Leitungen mit RS-232-Empfangs- und Sendeleitungen verbunden und irgendwie erwartet haben, dass alles funktioniert. Die vom PIC verwendeten digitalen Logikpegel und die RS-232-Pegel sind nicht kompatibel, und High/Low sind ebenfalls invertiert. RS-232 sollte unter -5 V für Leitungsruhe (Leerzeichen) und über +5 V für aktiv (Markierung) liegen. Natürlich kann ein PIC diese Pegel beim Senden nicht garantieren und kann beim Empfang durch diese Pegel beschädigt werden. Die normalen digitalen Logikpegel sind hoch für Leerzeichen und niedrig für Markierungen, was auch der PIC tut, mit Ausnahme einiger begrenzter wie Ihrer, bei denen eine oder beide Leitungen invertiert werden können.

Einige RS-232-Empfängerchips spielen locker mit den RS-232-Spezifikationen und arbeiten mit 0-5-V-Signalen, die ihre Empfangsleitung ansteuern. Bei Ihrem PC ist dies anscheinend der Fall, weshalb Sie am PC bereits nach Invertieren der PIC-Sendeleitung Zeichen empfangen konnten. Damit die PC --> PIC-Übertragung funktioniert, müssen Sie das Signal invertieren und das Ergebnis dem Vss- bis Vdd-Bereich des PIC zuordnen. Andernfalls kann der PIC beschädigt werden, was möglicherweise bereits geschehen ist.

Aus diesem Grund wurde der Chiptyp MAX232 entwickelt. Dieser wird vom PIC Vdd und Vss gespeist, enthält seine eigenen Ladungspumpen, um die RS-232-Spannungen zu erzeugen, hat die richtigen Treiber- und Empfängerschaltkreise auf jeder Seite und führt auch die Inversion durch. Viele Unternehmen machen eine Reihe von Varianten davon. Dies sind sehr verbreitete und verfügbare Chips.

Sie können auch kleine Module erhalten, die den Konverterchip, die Ladungspumpe und die Stromversorgungskappen sowie den Standard-DB-9-Anschluss in einer einzigen Einheit enthalten. Ich mache eine davon, die sogar auf Microchipdirect verkauft wird. Siehe http://www.microchipdirect.com/ProductSearch.aspx?Keywords=TEMRS002 .

Um Ihre Frage zu beantworten, verwende ich ein vermutlich sehr verbreitetes Setup: Win7 mit TeraTerm auf der einen Seite und PIC16 auf der anderen Seite. Sollte UART nicht "einfach funktionieren"?
@Random: Absolut nicht, wie schon ein flüchtiger Blick auf die relevanten Spezifikationen ergeben hätte. Das direkte Anschließen eines PIC an einen RS-232 kann den PIC beschädigen und nicht die richtigen Pegel auf der RS-232-Seite liefern, selbst wenn Sie die Logiksignale einfach invertiert haben. Aus diesem Grund gibt es Chips wie den gängigen MAX232 und seine vielen Varianten und Imitate. Sie müssen wirklich gelegentlich einige Spezifikationen lesen .
Sie haben keine Ahnung, wie oft ich das EUSARTKapitel (ab Seite 291 des PIC16-Datenblatts ) gelesen habe. Es gibt keine Erwähnung oder Warnung bezüglich direkter Verbindungen zu RS232 oder dem MAX232. Wo bin ich im Prozess gescheitert? Meine Annahme war, dass das PIC16-Datenblattkapitel zu EUSART den allgemeinen Anwendungsfall abdecken würde: RS232.
Das Datenblatt erwähnt maximale Eingangspegel an jedem Pin. RS232 liegt weit außerhalb dieser Werte. Es liegt nicht wirklich im Bereich des PIC16-Datenblatts zu erklären, wie man sie konvertiert. Wenn Sie versuchen, zwei Dinge zu verbinden, können Sie im Allgemeinen nicht erwarten, alle Ihre Informationen zu erhalten, wenn Sie die Spezifikationen für nur eines von ihnen lesen.
@Random: Es ist nicht die Aufgabe von Microchip, und es würde das Datenblatt überladen, RS-232 zu erklären oder welche Konvertierungen erforderlich sind, um den PIC mit etwas anderem zu verbinden. Sie dokumentieren, was der PIC tut. Es ist Ihre Aufgabe zu wissen, woran Sie den PIC anschließen, und alle Schnittstellenschaltungen hinzuzufügen, die basierend auf den Spezifikationen der anderen Seite erforderlich sein können.