Class5_serial_4499720bc7a8e92d93bc02127b475680
Class5_serial_4499720bc7a8e92d93bc02127b475680
Microcontrollers and
Embedded Systems
Week 8: Serial Communication
1
Learning Objectives
2
ATmega328 Pin-out
3
Parallel vs Serial
• Parallel • Serial
• For short distances • Less wires
• Not applicable for long distances • Slower
• More expensive
• Cross-talk problem
Sepehr Naimi, Sarmad Naimi, and Muhammad Ali Mazidi. 2017. The AVR Microcontroller and Embedded Systems Using Assembly and C: Using Arduino Uno and Atmel Studio [Textbook Slides]. Retrieved from : https://nicerland.com/avr/ 4
Communication Modes
• Simplex
• Half-Duplex
• Full-Duplex
5
Synchronous vs Asynchronous
• Synchronous:
• Asynchronous:
6
Common Serial Interfaces
• USART (RS232)
• USB
• Controller Area Network (CAN)
• Serial Peripheral Interface (SPI)
• Inter-Integrated Circuit(I2C)
• Ethernet
• 1-wire
7
RS232
• USART
• Common in old PCs
• 9 pins (or 25)
• 3 lines minimum required: TxD, RxD and ground
• Voltage levels:
- 0: +3 to +15 V
- 1: -15 to -3 V
• RS422: twisted pairs
8
TTL-to-RS232: MAX232 IC
Sepehr Naimi, Sarmad Naimi, and Muhammad Ali Mazidi. 2017. The AVR Microcontroller and Embedded Systems Using Assembly and C: Using Arduino Uno and Atmel Studio [Textbook Slides]. Retrieved from : https://nicerland.com/avr/ 9
Serial Communication - USART
10
UART Data Framing
• Frame:
- Start bit
- Data bits (5,6,7,8 or 9)
- Stop bit(s)
- Parity: optional
Start LSB X X X X X MSB Parity Stop
11
UART Data Framing
12
UART in ATMega328P
13
UART – ATMega328P Registers
UDR0 RXB[7:0]
TXB[7:0]
UCSZ01 / UCSZ00 /
UCSR0C UMSEL01 UMSEL01 UPM01 UPM00 USBS0 UCPOL0
UDORD0 UCPHA0
UBRR0L UBRR0[7:0]
UBRR0H UBRR0[3:0]
14
UDR0
UDR0 RXB[7:0]
TXB[7:0]
15
UCSR0A
UCSR0A RXC0 TXC0 UDRE0 FE0 DOR0 UPE0 U2X0 MPCM0
UBRR0H UBRR0[11:8]
• USART Baud Rate 0 Register: 12-bit register which contains the USART baud rate
• Ongoing transmissions by the Transmitter and Receiver will be corrupted if the baud
rate is changed.
• Writing UBRR0L will trigger an immediate update of the baud rate prescaler.
Operating Mode Baud Rate (bps) UBRRn Value
𝑓𝐶𝑃𝑈 𝑓𝐶𝑃𝑈
Asynchronous Normal mode (U2Xn = 0) Baud = UBRRn= −1
16 𝑼𝑩𝑹𝑹𝒏+1 16 𝐵𝐴𝑈𝐷
𝑓𝐶𝑃𝑈 𝑓𝐶𝑃𝑈
Asynchronous Double Speed mode (U2Xn = 1) Baud = UBRRn= −1
8 𝑼𝑩𝑹𝑹𝒏+1 8 𝐵𝐴𝑈𝐷
21
Baud rate Calculations
Baud Rate U2Xn = 0 U2Xn = 1
[bps] UBRRn Error UBRRn Error
• 9600 bps 2400 416 –0.1% 832 0.0%
4800 207 0.2% 416 –0.1%
9600 103 0.2% 207 0.2%
14.4k 68 0.6% 138 –0.1%
19.2k 51 0.2% 103 0.2%
28.8k 34 –0.8% 68 0.6%
• 115200 bps 38.4k
57.6k
25
16
0.2%
2.1%
51
34
0.2%
–0.8%
76.8k 12 0.2% 25 0.2%
115.2k 8 –3.5% 16 2.1%
230.4k 3 8.5% 8 –3.5%
250k 3 0.0% 7 0.0%
0.5M 1 0.0% 3 0.0%
1M 0 0.0% 1 0.0%
2M - - 0 0.0%
22
Clock Generation Logic, Block Diagram
23
UART – Programming the AVR (TX)
24
UART – Programming the AVR (RX)
25
ee470avr.h
void serial_init(unsigned int ubrr) {
UBRR0 = ubrr;
UCSR0A = 0;
UCSR0B = 0b00011000; // no int.,Rx&Tx enable
UCSR0C = 6; // asynch mode, 8bit, 1stop, no parity
}
void putch( unsigned char ch ) {
// first wait for empty transmit buffer
while(bittst(UCSR0A,UDRE0)==0);
UDR0 = ch; // send character return;
}
unsigned char getch(void) {
// first wait till byte received (start,data bits,stop)
while(bittst(UCSR0A,RXC0)==0);
return(UDR0); // return received char as the value of the function
}
26
ee470avr.h
void putch( unsigned char ch ) {
// first wait for empty transmit buffer
while(bittst(UCSR0A,UDRE0)==0);
UDR0 = ch; // send character return;
}
void putstr(char line[]) {
unsigned char i=0;
// in C-language, strings are NULL (ASCII 0) terminated arrays of characters
while(line[i] != '\0’) {
putch(line[i]);
i++;
}
}
27
ee470avr.h
// using the ee470avr.h getch and putch functions
#include "ee470avr.h"
void main(void)
{ unsigned char c;
serial_init(103); // 9600, 8d, 1stop, no parity
while(1)
{ c = getch(); // wait for character from kbd
putch(c); // send it to screen
}
}
28
Example
/* mnn2ec11x17.c
Program the ATmega328 to receive bytes of data serially and put them on Port B.
Set the baud rate at 9600, 8-bit data, and 1 stop bit. Use Receive Complete interrupt instead
polling */
#include “ee470avr.h”
ISR(USART_RX_vect) {
PORTB = UDR0;
}
int main (void) {
DDRB = 0xFF; //make Port D an output
bitset(UCSR0B,RXEN0);
bitset(UCSR0B,RXCIE0); //enable receive and RXC int
bitset(UCSR0C,UCSZ01);
bitset(UCSR0C,UCSZ00);
UBRR0 = 103;
sei(); //enable interrupts
while (1); //wait forever
}
29
Example
/* mnn2ec11x18.c:
Program the ATmega328 to send “G” serially.
Set the baud rate at 9600, 8-bit data, and 1 stop bit. Use interrupt instead of polling */
#include “ee470avr.h”
ISR(USART_UDRE_vect) {
UDR0='G';
}
int main (void) {
DDRB = 0xFF; //make Port B an output
bitset(UCSR0B,TXEN0);
bitset(UCSR0B,UDRIE0); //enable transmit and UDRIE0 int.
bitset(UCSR0C,UCSZ01);
bitset(UCSR0C,UCSZ00);
UBRR0 = 103;
sei(); //enable interrupts
while (1); //wait forever
}
30