• Keine Ergebnisse gefunden

Serielle Kommunikation mit UART/USART

N/A
N/A
Protected

Academic year: 2021

Aktie "Serielle Kommunikation mit UART/USART"

Copied!
28
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

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)

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 senden

CTS: Eingang, Clear To Send, Bereitschaft Daten zu empfangen Tx : Data Transmitter, Datensendeleitung

Rx : Data Receiver; Datenempfangsleitung

RTS/CTS dienen dem Hardware Handshake

(3)

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)

5

Pins Sub-D 9, Sub-D 25

PCCOM1 PCCOM2

RS232 Bezeichnung

1 8 DCD in

2 3 in Empfangsdaten

3 2 Sendedaten

4 20 DTR

5 7 GND

6 6 DSR in

7 4 RTS

8 5 CTS in

9 22 RI in

- 12

- 23 SPDS

9Pol männl 25Pol männl

Data Carrier Detect RxD

TxD out

out Data Terminal Ready

Ground - Bezugspotential Data Set Ready

out Request to send Sendeanfrage Clear to send

Ring Indicator (Klingel)

SpeedModeDetector

Speed select

(5)

6

Übertragungsprotokoll

http://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.

(6)

7

Baudrate

http://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.

(7)

8

Anschluss UART/MAX232

USB-UART-Adapter:

sw : GND

rt : +5V offen lassen, wenn Programmer dran ws : tx

gr : rx

(8)

9

Steuerregister des USART des Atmega

Port Funktion Port-Adresse RAM-Adresse UCSRAUSART Status Register0x0B 0x2B

7 6 5 4 3 2 1 0

RXC TXC UDRE FE OR PE U2X MPCM

Bit Name Bedeutung Funktion

7 RXC UART Receive Complete 1: Zeichen empfangen/0: Kein Zeichen 6 TXC UART Transmit Complete 1: Daten aus Schieberegister gesendet 5 UDRE UART Data Register Empty1: Senderegister frei

4 FE Framing Error 1: Ungültiges Stop-Bit

3 DOR Overrun 1: Zeichenverlust

2 PE Paritätskontrolle 1:Paritätsfehler 1 U2X doppelte Baudrate

0 MPCM Multiprozessorbetrieb (Daten/Adressen)

(9)

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

(10)

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: UCSRC 0: UBRRH

6 UMSEL synchron/asynchron 0:Asyn, 1: Synchon

5 4

UPM1 UPM0

Parität 00:none

01:reserved 10:even 11:odd

3 USBS stopp bits 0:1 Stoppbit

1:2 Stoppbits

2 UCSZ1

UCSZ0 Zeichenlänge zusammen mit UCSZ2 aus

UCSRB 000:5 bit

001:6 bit 010:7 bit 011:8 bit 111:9 bit 0 UCPOL Synchon: Phasenlage

(11)

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

(12)

13

Port Funktion Adresse Ramadresse

UDR UART I/O Data

Register 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∗UBRR 1

BAUD = FCPU

8∗ UBRR 1  Mit math. Runden

Mit Abschneiden

(C-like)

(13)

14

Tabelle für UBRR

1 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 = BAUD

res

BAUD −1 ∗ 100

Es wird dringend empfohlen, einen mit einem Quarz

stabilisierten Oszillator zu verwenden

(14)

15

Tabelle für UBRR

11,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%

(15)

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

(16)

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 enable

UCSRB = (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)

(17)

18

USART Init

funktioniert mit 8MHz und 9600 Baud

/* Initialization of USART */

void USART_Init( unsigned int ubrr) {

/* Set baud rate */

UBRRH = (unsigned char) (ubrr >> 8);

UBRRL = (unsigned char) ubrr;

/* Enable receiver and transmitter */

/* Interrupt bei Empfang */

UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);

/* Set frame format: 8data, 1stop bit, synchronous operation */

UCSRC = (1 << URSEL) |(1<<UCSZ1)|(1<<UCSZ0);

do {

uint8_t dummy;

(void) (dummy = UDR);

}

while (UCSRA & (1 << RXC));

sei();

}

/* Initialization of USART */

void USART_Init( unsigned int ubrr) {

/* Set baud rate */

UBRRH = (unsigned char) (ubrr >> 8);

UBRRL = (unsigned char) ubrr;

/* Enable receiver and transmitter */

/* Interrupt bei Empfang */

UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);

/* Set frame format: 8data, 1stop bit, synchronous operation */

UCSRC = (1 << URSEL) |(1<<UCSZ1)|(1<<UCSZ0);

do {

uint8_t dummy;

(void) (dummy = UDR);

}

while (UCSRA & (1 << RXC));

sei();

}

(18)

19

/* 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)

20

Byte empfangen

Hier 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)

21

Ausgabe auf USART

void 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;

}

Data Register Empty

(21)

22

Der PC, die andere Seite, init

int 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)

23

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)

24

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 -echo

Lesen ist mit cat möglich:

cat < /dev/ttyUSB0

Senden mit echo xxx > /dev/ttyS0

Ubuntu: Anwendungen → Zubehör → Serial port terminal

(24)

25

RS485

Basiert ebenfalls auf serieller Übetragung

Andere elektrische Umsetzung über zwei Leitungen A und B.

Spannungspegel auf den Leitungen „spiegeln“

sich, dadurch wird eine große Störsicherheit gewährleistet.

Basiert ebenfalls auf serieller Übetragung

Andere elektrische Umsetzung über zwei Leitungen A und B.

Spannungspegel auf den Leitungen „spiegeln“

sich, dadurch wird eine große Störsicherheit gewährleistet.

0 1 1 1 0

A

B A: Invertiert

B nicht Invertiert A-B < 0,25V → 1 A-B > 0,25V → 0 A: Invertiert

B nicht Invertiert A-B < 0,25V → 1 A-B > 0,25V → 0

(25)

26

RS485

Mehrere Geräte können an einem Bus verbunden sein.

Ein übliches Protokoll ist Modbus RTU.

Ein Gerät startet die Kommunikation und

sendet eine Geräteadresse,ein Kommando, eine Registeradressse, eine Anzahl von

Registern und ggf. Werte, wenn Werte

geschrieben werden sollen. Abgeschlossen wird das Ganze mit einer Prüfsumme.

Mehrere Geräte können an einem Bus verbunden sein.

Ein übliches Protokoll ist Modbus RTU.

Ein Gerät startet die Kommunikation und

sendet eine Geräteadresse,ein Kommando, eine Registeradressse, eine Anzahl von

Registern und ggf. Werte, wenn Werte

geschrieben werden sollen. Abgeschlossen

wird das Ganze mit einer Prüfsumme.

(26)

27

RS485

unsigned char requestString[] ={

0xf7, // device 0x03, // command

0x13, 0xB2, // Register (big endian)

0x00, 0x0b, // number of registers (big endian) 0x00, 0x00 // CRC (little endian)

};

uint16_t ModRTU_CRC(uint8_t * buf, int len) {

uint16_t crc = 0xFFFF;

for (int pos = 0; pos < len; pos++) {

crc ^= (uint16_t)buf[pos]; // XOR byte into least sig. byte of crc

for (int i = 8; i != 0; i--) { // Loop over each bit if ((crc & 0x0001) != 0) { // If the LSB is set

crc >>= 1; // Shift right and XOR 0xA001 crc ^= 0xA001;

}

else // Else LSB is not set crc >>= 1; // Just shift right }

}

// Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes) return crc;

}

Berechnung CRC

(27)

28

RS485

Das angesprochene Gerät sendet dann eine Antwort, bestehend aus

– Device (1 Byte)

– Command (1Byte)

– Start Register (2 Byte big endian)

– Numb Register (2 Byte big endian)

– Values (2 Bytes/4Bytes big endian

– …

– CRC

Das angesprochene Gerät sendet dann eine Antwort, bestehend aus

– Device (1 Byte)

– Command (1Byte)

– Start Register (2 Byte big endian)

– Numb Register (2 Byte big endian)

– Values (2 Bytes/4Bytes big endian

– …

– CRC

(28)

29

Modbus- Geräte:

Elektronische Zähler SDM630-M oder SDM230-M

Solarlageregler Tracer

Lithium Batterie Renogy

Elektronische Zähler SDM630-M oder SDM230-M

Solarlageregler Tracer

Lithium Batterie Renogy

Referenzen

ÄHNLICHE DOKUMENTE

mySTM32-Board-F4D mit dem Board STM32F4-Discovery, Beispiel für UART Kommunikation mySTM32-Board-F4D and STM32F4-Discovery, example for UART communication. Abbildung

Zwei der drei ESP8266s habe ich auf je einen der Rover platziert, damit diese mittels UART mit dem TI-System kommunizieren können.. Der HUB hat eine entsprechende

MOSI Master out, Slave in (ausgehende Datenleitung) MISO Master in, Slave out (eingehende Datenleitung) SS Slave Select.. Daisy

 Eigenständiges Bauelement oder Bestandteil eines anderen Bauteils...  UART: Universal Asynchronus Reciever and

[r]

Daten¨ ubertragung wird intern abgesprochen und ist nicht von einer Takt-Leitung (SCK) abh¨ angig?. Maik

 Atmega32 mit Register für Serielle Signale.  UART mit Interrupts

[r]