Serielle Schnittstelle
RS-232 ist ein Standard für eine bei Computern teilweise vorhandene serielle Schnittstelle, der in den frühen 1960er Jahren von dem US-amerikanischen Standardisierungskomitee Electronic Industries Association (EIA) erarbeitet wurde. (wikipedia WP)
Die Übertragung erfolgt in Wörtern
-
Eine RS-232-Verbindung arbeitet (bit-)seriell mit je einer Datenleitung für beide Übertragungsrichtungen. Das heißt, die Bits werden nacheinander auf einer Leitung übertragen, im Gegensatz zur parallelen Datenübertragung. Die dafür nötige Seriell-Parallel-Wandlung geschieht meistens in sog. UARTs (entweder als integriertes Modul in einem Mikrocontroller oder als Einzelbaustein).
-
Die Datenübertragung erfolgt asynchron, es existiert also kein gemeinsamer Takt.Die Synchronisation in der Übertragung erfolgt durch den Empfänger als sogenannte Wortsynchronisation, also am Anfang durch die Signalflanke des Startbits.
-
Vereinbarung der Baudrate (=Anzahl der Symbole / Sekunde) zwischen Sender und Empfänger (9600, 19200, ... 115200)
-
Die Synchronisation des Empfängers geschieht mit dem Start der Übertragung auf der Datenleitung, da das Stopp-Bit bzw. der Ruhezustand auf der Leitung den inversen Pegel zum Start-Bit aufweist. Der Empfänger synchronisiert sich so in die Mitte der einzelnen Datenbits und tastet die folgenden Bits des Datenwortes mit seiner eigenen Bitrate ab.
-
Damit das funktioniert, dürfen die Bitraten von Sender und Empfänger nur einige Prozent voneinander abweichen (ca. 3%).
-
Jedes übertragene Wort muss somit von einem Startbit (logischer Wert 0) eingeleitet und mit mindestens einem Stopp-Bit (logischer Wert 1) abgeschlossen werden.
-
RS-232 ist eine Spannungsschnittstelle (im Gegensatz z.B. zu einer Stromschnittstelle). Die binären Zustände werden durch verschiedene elektrische Spannungspegel realisiert.
-
Für die Datenleitungen (TxD und RxD) wird eine negative Logik verwendet, wobei eine Spannung zwischen −3 V und −15 V eine logische Eins bedeutet. Signalpegel zwischen −3V und +3V gelten als undefiniert.
-
Bei den Steuerleitungen (DCD, DTR, DSR, RTS, CTS und RI) wird positive Logik verwendet.
-
Steckverbindung: 9-polige D-Sub-Stecker und Buchsen
Handshake: Zur Vermeidung von Datenverlusten muss der Empfänger die Datenübertragung anhalten können, wenn keine weiteren Daten mehr verarbeitet werden können.
softwareseitig über bestimmte Steuercodes
oder über spezielle Leitungen (Hardware-Handshake).
-
Grundsätzlich ist eine Vollduplex-Verbindung möglich, da für Sendung und Empfang getrennte Datenleitungen zur Verfügung stehen.
-
Kabellänge:Laut ursprünglichem Standard ist eine Kabelkapazität von max. 2500 pF zulässig, was bei Standardkabeln einer Kabellänge von max. 15 m
-
RS232 Treiber Bausteine zur Erzeugung der Hochspannung (+-10V)
-
Parity; odd/even prüft, ob die Gesamtzahl der 1 inklusive Parity-Flag gerade oder ungerade ist z.B: Sender und Empfänger vereinbaren 8Bit even Parity: das 8.Bit ist das Parity-Bit: gesendet: 1101 0010 , aber empfangen wurde 1100 0010 → liefert einen Parity-Error
-
Konfiguration der Seriellen Schnittstelle 9600 8N1 (9600 Baud, 8 Bit Daten, keine Paritätsprüfung, 1 Stopbit
AVR UART
Data Register UDR
Control Register UCR
Baud Rate Register UBR
Status Register USR
Control&Status Register UCSR
Status Flags
-
Receive Complete
-
Transmit complete
-
Data register empty
-
Error
Control Register
-
Rx Complete Interrupt Enable
-
Tx Complete Interrupt Enable
-
Receive enable
-
Transmit enable
Data Register
-
Physikalisch getrennte Register für Senden und Empfangen, aber beide Register heißen gleich (z.B: UDR0)
Baudrate
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART#UART_initialisieren
#define F_CPU 4000000UL // Definition als unsigned long beachten
// Ohne ergeben sich unten Fehler in der Berechnung
#define BAUD 9600UL // Baudrate
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // Wert für das Baudratenreg.
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif
Initialisierung
void uart_init(void)
{
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
UCSRB |= (1<<RXEN); // UART RX einschalten
UCSRB |= (1<<TXEN); // UART TX einschalten
}
Daten senden
/* ATmega16 */
int uart_putc(unsigned char c)
{
while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
{
}
UDR = c; /* sende Zeichen */
return 0;
}
/* puts ist unabhaengig vom Controllertyp */
void uart_puts (char *s)
{
while (*s)
{ /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
uart_putc(*s);
s++;
}
}
Daten empfangen
uint8_t uart_getc(void)
{
while (!(UCSRA & (1<<RXC))) // warten bis Zeichen verfuegbar
;
return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben
}