Softwareemulation eines RS232-Interfaces mit dem PIC16F84.
Während der größere PIC16F876
die
Hardware
für
ein
serielles Interface enthält, steht die
serielle Kommunikation mit einem PC oder Palm-Pilot dem kleinen 16F84
nicht
so ohne weiteres zur Verfügung. Da das RS232-Protokoll
aber sehr einfach ist, kann man es mit etwas Software
nachempfinden.
RS-232 ist eine serielle Übertragung, bei der das Datenbyte mit dem LSB (Bit 0) voran übertragen wird. Unmittelbar vor dem ersten Datenbit wird ein Startbit mit dem Wert "0" übertragen, nach dem Datenwort folgt eine "1" als Stopbit. (Es gibt Modifikationen mit nur 7 Bit oder mit zusätzlichem Prüfbit aber das ist jetzt nicht wichtig.)
In einem normgerechten RS232-Kabel wird eine "1" wird als ein -12V-Signal übertragen und eine "0" als ein +12V-Signal. Erfahrungsgemäß funktioniert die Verbindung aber auch bei verminderten Pegeln, wenn anstelle von +12V und -12V einfach +5V und 0V verwendet werden. Damit ergibt sich für unser Lernbeispiel folgendes Zeit/Spannungsdiagramm.
++HINWEIS++
Normalerweise werden spezielle
Treiberschaltkreise
verwendet, um beim Senden den TTL-Pegel (5V) auf den RS232-Pegel (12V)
und beim Empfangen den RS232-Pegel wieder auf TTL-Pegel zu
wandeln.
Es hat sich eingebürgert, dass diese Schaltkreise die Pegel nicht
nur anpassen, sondern auch invertieren. Dabei wird also 5V zu -12V und
0V zu +12V. Deshalb wird dann auf der TTL-Seite der Treiber eine '0' zu
0V und eine'1' zu 5V. Da in unserem Beispiel keine Treiber verwendet
werden,
muss unser PIC direkt die inversen Pegel erzeugen und empfangen. Daraus
ergibt sich oben stehendes Diagramm mit inversen Pegeln.
Die Länge eines jeden Bit ist gleich, und ergibt sich aus der
Baudrate.
Verschiedene Baudraten sind üblich, z.B.:
Baudrate | Bitlänge |
300 Baud | 3,33 ms |
2400 Baud | 417 µs |
9600 Baud | 104 µs |
38400 Baud | 26,04 µs |
Da es kein zusätzliches Synchronisiersignal gibt, muss die Datenrate bei Sender und Empfänger gleich eingestellt sein, und darf um höchstens 5% vom Sollwert abweichen.
Eine detailliertere Beschreibung der RS232-Schnittstelle findet man hier.
Schaltung
Auf den nachfolgenden Bildern sind als RS232-Steckverbinder Sub-D9-Buchsen
verwendet worden. Die Schaltung kann an einen PC mit Hilfe eines
normalen
RS232 Kabels (kein Null-Modem-Kabel !!) angeschlossen werden.
Ein normgerechtes RS232-Interface überträgt eine "1" mit
einem
-12V-Signal und eine "0" mit einem +12V-Signal. Das erfordert spezielle
Treiberhardware.
Für die kurze Verbindung zum PC oder Palm-Pilot reicht aber
erfahrungsgemäß
0V für "1" und +5V für "0".
Senden (vom PIC zum PC): Die Treiber spare ich deshalb ein und verbinde eine PIC-Ausgangsleitung (vorzugsweise Port A) mit der Daten-Eingangsleitung des PC. Das in am 9-poligen PC-Anschluss Pin 2. Masse des PIC wird mit dem Masseanschluss Pin5 am PC verbunden. Außerdem sind zwei Brücken am 9-poligen PC-Anschluss nötig: Pin7--Pin8, und Pin4--Pin6. |
Empfangen (vom PC zum PIC): Der PC sendet mit +12V und -12V-Pegel. Beide Pegel sind für den PIC tödlich, wenn keine spezielle Vorkehrung getroffen werden. Als Schutz reicht ein Widerstand von 22kOhm oder 27kOhm, der zwischen dem Datenausgang des PC (Pin3 des 9-poligen Anschlusses) und dem Eingangspin des PIC (vorzugsweise am Port A) geschaltet wird. Die Masseverbindung und die zwei Brücken müssen wie beim Senden gezogen werden. Es eignet sich z.B. die 16F84-Testplatine
oder |
Hinweis:
Wer die obigen Schaltungen mit richtigen
RS232-Treibern
(MAX222 o.ä.) komplettieren will, muss die Software so
ändern,
dass beim Senden die RS232-Signale invertiert werden, und dass beim
Empfangen
inverse Pegel erwartet werden.
Programmablauf
Senden:
Empfangen:
Programmdetails
Senden:
Die Routine Send_RS sendet zunächst ein Stop-Bit (1), dann ein
Start-Bit (0), dann nacheinander die 8 Bits des zu sendenden Bytes und
schließlich ein Stop-Bit (1). Dafür wird jeweils das Pin RA2
auf den entsprechenden Pegel gesetzt (1=low und 0= high) und
anschließend
für die Länge eines Bits gewartet.
Diese Wartezeit von 1 Bit wird mit der Routine Warte_s erledigt. Die Wartezeit ist von der gewünschten Baudrate der RS-232-Verbindung und vom PIC Takt abhängig. Das Prinzip der Warteschleifen habe ich schon in einem anderen Beispiel erläutert.
Bei 9600 Bps ist ein Bit genau 1/9600 Sekunde lang, das sind 104
µs.
Bei einem PIC-Takt von 4 MHz, werden Befehle im PIC mit einem Zyklustakt
von 1 MHz abgearbeitet. Jeder Befehl (mit Ausnahme der wenigen Befehle,
die 2 Zyklen lang sind) dauert folglich 1 µs.
Die Schleife von 'Warte1' bis zu 'goto Warte1' ist im Programm 6 Zyklen
lang (goto benötigt 2 Zyklen), ein Durchlauf benötigt
folglich
6 µs. Um 1 Bit lang (also 104µs) zu verzögern, muss
man die Schleife 15 mal durchlaufen. Diese Durchläufe
benötigen
90µs. Die noch verbleibenden 14 µs verbrauchen der
Aufruf
von Warte_s, das Laden von cycl_2 sowie das Return.
;**********************************************************
;ein Bit Zeitverzoegerung mit einer Warteschleife ; ; senden 4 MHz 10 MHz ; 2400 Bps = 69d 173d ; 9600 Bps = 15d 43d Warte_s movlw
D'15'
; 9600 Bps / 4 MHz senden |
Programmlisting
Senden:
Das Testprogramm sendet in einer Endlosschleife den Buchstaben "A".
Als PIC-Takt muss 4 MHz verwendet werden. Die Datenrate ist 9600 Baud.
Die übrigen Parameter sind: 8 Bit, 1 Startbit, 2 Stopbits, kein
Paritätsbit.
Für andere Datenraten oder einen anderen PIC-Takt müssen
die Timings im Quelltext verändert werden.