Serielle Kommunikation mit UART/USART - HTW Dresdenbeck/Atmel/Vorlesungen/Micro_RS232.pdf · 11...
Transcript of Serielle Kommunikation mit UART/USART - HTW Dresdenbeck/Atmel/Vorlesungen/Micro_RS232.pdf · 11...
1
Serielle Kommunikation mit UART/USART
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART
●Serielle Kommunikation mit RS232●Seit 1962 !●Spezifikation regelt elektrische und mechanische Belange●Pegelanpassung zwischen TTL (0/5V) und RS232 (+/- ca.14V) nötig (MAX232)●-3..-25V: 1 | 3..25V: 0●Rx (PD0) / Tx (PD1) Pins beschalten (verbinden mit MAX232–Platine oder USB-Adapter
2
Der Serielle Port (die Leitungen)
Begriffe:DTE: Data Terminal Equipment (PC, Fax, verarbeitendes Gerät, male)DCE: Data Carrier Equipment (Daten transportierendes Gerät. Modem,.., fem)RTS: Ausgang, Redy To Send, Will Daten sendenCTS: Eingang, Clear To Send, Bereitschaft Daten zu empfangenTx : Data Transmitter, DatensendeleitungRx : Data Receiver; Datenempfangsleitung
RTS/CTS dienen dem Hardware Handshake
3
Handshake (Hardware)http://www.oliver-saal.de/elektronik/rs232.php
RTS
CTS
Request to Send„Sendeanforderung“; Ein High-Pegel an diesem Ausgang signalisiert, dass DTE Daten senden möchte
Clear to Send
„Sendeerlaubnis“; Ein High-Pegel an diesem Eingang ist ein Signal der Gegenstelle, dass sie Daten von DTE entgegennehmen kann
XON/XOFF bilden die Flowcontroll-Steuerzeichen (Xon = 11h und Xoff = 13h).
Es werden nur die Datenübertragungsleitungen benötigt
Die Zeichen 0x11 und 0x13 dürfen in den Daten nicht vorkommen
Handshake (Software)
4
Steckverbinderhttp://www.camiresearch.com/Data_Com_Basics/RS232_standard.html
http://www.frontx.com/pro/cpx102_2.html, http://www.lammertbies.nl/comm/cable/RS-232.html
Mainboardconnector (female, Weibel)
Sicht auf die Stifte (male, Männel)
5
Pins Sub-D 9, Sub-D 25
PCCOM1 PCCOM2RS232 Bezeichnung
1 8 DCD in2 3 in Empfangsdaten3 2 Sendedaten4 20 DTR5 7 GND6 6 DSR in7 4 RTS8 5 CTS in9 22 RI in- 12- 23 SPDS
9Pol männl 25Pol männlData Carrier Detect
RxDTxD out
out Data Terminal ReadyGround - BezugspotentialData Set Ready
out Request to send SendeanfrageClear to send Ring Indicator (Klingel)SpeedModeDetectorSpeed select
6
Übertragungsprotokollhttp://www.mikrocontroller.net/articles/RS-232
Anmerkungen:1: low Pegel (-15..-3V)0: high Pegel (3.. 15V)
Modus : 8N1 (8 Datenbit, no parity bit, 1 Stopp Bit)Baud : 9600 Baud Übertragungsgeschwindigkeit s. u.
7
Baudratehttp://www.bluray-disc.de/lexikon/baudrate
Die Baudrate ist die Größe, die in der Nachrichten- und Übertragungstechnik die Signalrate angibt. Sie steht für die Anzahl der Zustands- oder Symboländerungen in einer bestimmten Zeiteinheit an, die eine Übertragung erfährt.
Die Einheit der Baudrate ist 1 Baud [1 Bd], benannt nach dem französischen Wissenschaftler Jean-Maurice-Emile Baudot, dem zahlreiche Erfindungen auf dem Gebiet der Telegrafie zu verdanken sind.
Die Baudrate wird häufig mit der Bitrate verwechselt. Die Bitrate steht im Gegensatz zur Baudrate aber für die Datenrate. Baudrate und Bitrate sind gleich, wenn ein Symbol (0/1) genau einem Bit entspricht.
8
Anschluss UART/MAX232
USB-UART-Adapter:sw : GNDrt : +5V offen lassen, wenn Programmer dranws : txgr : rx
9
Steuerregister des USART des Atmega
Port Funktion Port-Adresse RAM-AdresseUCSRAUSART Status Register0x0B 0x2B
7 6 5 4 3 2 1 0RXC TXC UDRE FE OR PE U2X MPCM
Bit Name Bedeutung Funktion7 RXC UART Receive Complete 1: Zeichen empfangen/0: Kein Zeichen6 TXC UART Transmit Complete 1: Daten aus Schieberegister gesendet5 UDRE UART Data Register Empty1: Senderegister frei4 FE Framing Error 1: Ungültiges Stop-Bit3 DOR Overrun 1: Zeichenverlust2 PE Paritätskontrolle 1:Paritätsfehler1 U2X doppelte Baudrate0 MPCM Multiprozessorbetrieb (Daten/Adressen)
10
Bit Name Bedeutung
7 RXCIE enable Interrupt receive complete
6 TXCIE enable Interrupt transmit complete
5 UDREIE enable Interrupt transmit data register free
4 RXEN enable Receive
3 TXEN enable transmit
2 UCSZ2 Zeichenlänge zusammen mit UCSZ1 und UCSZ0 aus UCSRC
1 RXB8 9. Bit received
0 TXB8 9. Bit transmit
7 6 5 4 3 2 1 0
RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RXB8 TXB8
Port Funktion Port-Adresse RAM-Adresse
UCSRB USART Steuer Register 0x0A 0x2A
11
Port Funktion Port-Adresse RAM-Adresse
UCSRC USART Steuer Register 0x20 0x40
7 6 5 4 3 2 1 0
URSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL
Bit Name Bedeutung Funktion
7 URSEL 1: immer, wenn UCSRC angesprochen werden soll, weil UBRRH die selbe Adresse hat
1: UCSRC0: UBRRH
6 UMSEL synchron/asynchron 0:Asyn, 1: Synchon
5
4
UPM1
UPM0
Parität 00:none01:reserved10:even11:odd
3 USBS stopp bits 0:1 Stoppbit1:2 Stoppbits
2 UCSZ1UCSZ0
Zeichenlänge zusammen mit UCSZ2 aus UCSRB
000:5 bit001:6 bit010:7 bit011:8 bit111:9 bit
0 UCPOL Synchon: Phasenlage
12
Synchroner/Asyncroner Modus
● Synchron:– Noch nicht getestet
– Auf zusätzlicher Taktleitung wird ein Übertragungstakt geschaltet
– Bei Atmega XCK (PD4)
● Asynchron:– Es wird ein Datenstrom von Bits übertragen
– Start- Stopbit Kennzeichnen Anfang und Ende einer Übertragung
13
Port Funktion Adresse Ramadresse
UDR UART I/O DataRegister
0x0C 0x2C
UBRRH Baudratenregister(high)
0x20 0x40
UBRRL Baudratenregister(low)
0x09 0x29
Das UART DATA Register (UDR) besteht eigentlich aus den Registern UDR transmit und UDR receive. Beide werden über die selbe Adresse angesprochen, offenbar erfolgt die Unterscheidung an Hand der Lese-/Schreiboperation
Mode Calulating UBRR Calculating result. BAUD
Normal mode(asynchronous)
double speed
Aushttp://www.mikrocontroller.net/articles/AVR-Tutorial:_UART
UBRR=FCPU
16∗BAUD −1
UBRR=FCPU
8∗BAUD−1
UBRR=FCPUBAUD∗8
BAUD∗16−1
BAUD=FCPU
16∗UBRR1
BAUD=FCPU
8∗UBRR1
Mit math. Runden
Mit Abschneiden(C-like)
14
Tabelle für UBRR1 MHz 1,8432 MHz 2 MHz 3,686411 MHz 4 MHz 7,3728 MHz 8 MHz
2400 25 0,20% 47 0,00% 51 0,20% 95 0,00% 103 0,20% 191 0,00% 207 0,20%4800 12 0,20% 23 0,00% 25 0,20% 47 0,00% 51 0,20% 95 0,00% 103 0,20%9600 6 -7,00% 11 0,00% 12 0,20% 23 0,00% 25 0,20% 47 0,00% 51 0,20%
14400 3 8,50% 7 0,00% 8 -3,50% 15 0,00% 16 2,10% 31 0,00% 34 -0,80%19200 2 8,50% 5 0,00% 6 -7,00% 11 0,00% 12 0,20% 23 0,00% 25 0,20%28800 1 8,50% 3 0,00% 3 8,50% 7 0,00% 8 -3,50% 15 0,00% 16 2,10%38400 1 -18,60% 2 0,00% 2 8,50% 5 0,00% 6 -7,00% 11 0,00% 12 0,20%57600 0 8,50% 1 0,00% 1 8,50% 3 0,00% 3 8,50% 7 0,00% 8 -3,50%76800 0 -18,60% 1 -25,00% 1 -18,60% 2 0,00% 2 8,50% 5 0,00% 6 -7,00%
115200 0 -45,70% 0 0,00% 0 8,50% 1 0,00% 1 8,50% 3 0,00% 3 8,50%230400 0 -72,90% 0 -50,00% 0 -45,70% 0 0,00% 0 8,50% 1 0,00% 1 8,50%250000 0 -75,00% 0 -53,90% 0 -50,00% 0 -7,80% 0 0,00% 1 -7,80% 1 0,00%
Error=BAUDres
BAUD−1∗100
Es wird dringend empfohlen, einen mit einem Quarz stabilisierten Oszillator zu verwenden
15
Tabelle für UBRR11,0592 MHz 14,318 MHz 14,7456 MHz 16 MHz 18,432 MHz 20 MHz
2400 287 0,00% 372 0,00% 383 0,00% 416 -0,10% 479 0,00% 520 0,00%4800 143 0,00% 185 0,20% 191 0,00% 207 0,20% 239 0,00% 259 0,20%9600 71 0,00% 92 0,20% 95 0,00% 103 0,20% 119 0,00% 129 0,20%
14400 47 0,00% 61 0,20% 63 0,00% 68 0,60% 79 0,00% 86 -0,20%19200 35 0,00% 46 -0,80% 47 0,00% 51 0,20% 59 0,00% 64 0,20%28800 23 0,00% 30 0,20% 31 0,00% 34 -0,80% 39 0,00% 42 0,90%38400 17 0,00% 22 1,30% 23 0,00% 25 0,20% 29 0,00% 32 -1,40%57600 11 0,00% 15 -2,90% 15 0,00% 16 2,10% 19 0,00% 21 -1,40%76800 8 0,00% 11 -2,90% 11 0,00% 12 0,20% 14 0,00% 15 1,70%
115200 5 0,00% 7 -2,90% 7 0,00% 8 -3,50% 9 0,00% 10 -1,40%230400 2 0,00% 3 -2,90% 3 0,00% 3 8,50% 4 0,00% 4 8,50%250000 2 -7,80% 3 -10,50% 3 -7,80% 3 0,00% 4 -7,80% 4 0,00%
16
Empfehlungen zum Praktikum● Übertragungsprotokoll 8N1● 9600 Baud● Asynchone Übertragung● Übertragungsparameter müssen sende- und
empfangsseitig übereinstimmen● Empfang interruptgesteuert / Pollingbetrieb, je nach
Anwendungsfall● Quarz verwenden, make ext_11mhz,
F_CPU=11059200 einstellen● Empfangene Zeichen müssen auch „abgeholt
werden“, ansonsten kommt es zu Datenverlust
17
Initialisierung des USART// Baudratenteiler mit einem der beiden nachfolgenden Macros (empfohlen:9600Baud)#define UBRR ((F_CPU+BAUD*8)/(BAUD*16)-1) #define UBRR ((F_CPU/(16UL*BAUD))-1)
/* Baudrate einstellen*/UBRRH = (unsigned char) (UBRR_BAUD>>8);UBRRL = (unsigned char) UBRR_BAUD&0xff;// Aktivieren von receiver und transmitter// RXEN Receive enable// TXEN Transmit enable// RXCIE Receive complete Interrupt enableUCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit, keine Paritätskontrolle */UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // 8N1
// Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte)do{ uint8_t dummy; (void) (dummy = UDR);}while (UCSRA & (1 << RXC));
Empfang interruptgesteuert
URSEL immer angeben, wenn UCSRC angesprochen
wird
Bei 9600 BAUD und 11059200MHz sollten beide
Formen gehen (71)
18
/* Interrupt for USART, Rx Complete */ISR(USART_RXC_vect){static BYTE rcv_data, status; status = UCSRA; // erst Status lesen rcv_data = UDR; // dann Daten lesen /* Check for the error (High => error, Low => OK */ /* Flags: FE Frame Error; DOR Data OverRun; PE Parity Error */ if( status & ((1 << FE) | (1 << DOR) | (1 << PE)) )
{ if( status & (1 << FE)) PORTB |= 1 << PIN1; // 2. LED if( status & (1 << DOR))PORTB |= 1 << PIN2; // 3. LED if( status & (1 << PE)) PORTB |= 1 << PIN3; // 4. LED
} else { PORTB &= ~((1 << PIN1) | (1 << PIN2) | (1 << PIN3));
if(rcv_data == '1') PORTB |= 1 << PIN0; // Erste LED einschalten
if(rcv_data == '0') PORTB &= ~(1 << PIN0);// Erste LED ausschalten
}}
Byte empfangen
19
Byte empfangenHier ohne Statusabfrage, dafür mit Ringpuffer zum Zwischenspeichern empfangener Zeichen
unsigned char buffer[RING_SIZE];volatile unsigned short irr=0, irw=0;
ISR(USART_RXC_vect){ if(UCSRA&(1<<RXC)) { buffer[irw]=UDR; irw=(irw+1)%RING_SIZE; }}
short int ugetchar(void){ if (irr!=irw) { char c=buffer[irr]; irr=(irr+1)%RING_SIZE; return c; } else return 1;}
20
Ausgabe auf USARTvoid uputch(char x){ loop_until_bit_is_set(UCSRA, UDRE); UDR=x;}
void uputs(char * s){ int n=0; while(*(s))uputch(*s++),n++;}
void uputu(unsigned long d){ if (d>=10) uputu(d/10); uputch(d%10+'0');}
void uputd(long d){ if (d<0) {uputch('-');d=-d;} uputu(d);}
void uputx(unsigned long d){ if (d>=0x10) uputx(d/0x10); uputch(d%0x10>9?d%16+'A'-10:d%16+'0');}
char * itoadec (char * buf, int i, int len, char leading){ unsigned int itmp=i>0?i:-i; buf[len]=0; len --; while (len>=0) { if (itmp>0) buf[len--]=itmp%10+'0'; else buf[len--]=(buf[len+1]!=0)?leading:'0'; itmp/=10; } if (i<0)buf[0]='-'; return buf;}
char * itoahex (char * buf, unsigned int i, int len, char leading){ buf[len]=0; len --; while (len>=0) { if (i>0) buf[len--]=i%0x10<10? i%0x10+'0': i%0x10+'A'-10; else buf[len--]=leading; i/=0x10; } return buf;}
21
Der PC, die andere Seite, initint init(){ /*** Init ***/ //O_RDONLY, O_WRONLY or O_RDWR - //O_NDELAY (geht weiter, wenn keine Daten da sind und gibt "-1" zurueck) // man 2 open fuer mehr Infos - see man 2 for more info fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY); if (fd < 0){ printf("Fehler beim oeffnen von %s\n", MODEMDEVICE); exit(-1); } memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; //setzt die neuen Porteinstellungen newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; newtio.c_lflag = 0; /* set input mode (non-canonical, no echo, ...) */ newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ newtio.c_cc[VMIN] = 1; /* blocking read until 1 chars received */
tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &newtio); return fd;}
22
unsigned char receive(){ int res; unsigned char buffer;
res = read(fd, &buffer, 1); return buffer;}
unsigned char send(char c){ int res=write(fd, &c, 1); if (res<0) printf("Fehler beim Senden\n"); return res;}
PC, send, receive
23
Terminal als Gegenstelle● Initilisierung der seriellen Schnittstelle /dev/ttyS0, /dev/ttyUSB0 ….
● Verwendung von stty
● (stty -F /dev/ttyUSB0 ispeed 9600 ospeed 9600 cs8 clocal [ixoff])
● stty -F /dev/ttyUSB0 speed 9600
● Lesen ist mit cat möglich:
● cat < /dev/ttyUSB0
● Senden mit echo xxx > /dev/ttyS0
● Ubuntu: Anwendungen → Zubehör → Serial Port Terminal