Ich habe einen PIC16 , für den die (asynchrone) UART-Übertragung einwandfrei funktioniert, aber der UART-Empfang erzeugt ungültige Ergebnisse.
Wird beispielsweise a
als interpretiert O
, b
wird als interpretiert '
und c
wird 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 SCKP
Bit 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?
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.
O
(der Buchstabe), nicht eine 0
(die Zahl). Also 01100001
wird , 01100010
, 01100011
auf 01001111
, 00100111
abgebildet 01001110
. Denken Sie auch daran, dass Bits zuerst LSB gesendet werden. Wenn also die Empfangsleitung invertiert ist, ist das Startbit ganz rechts . 1
So 01100001
wird ~10110000
, 01100010
wird ~11011000
und 01100010
wird ~10100111
, alles passend zu dem, was ich empfange.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!?
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 .
EUSART
Kapitel (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.
Apalopohapa
Apalopohapa
Ole K
OSCCONbits.IRCF
Register richtig konfiguriert?