0% found this document useful (0 votes)
3 views

Lecture10_SerialCommunication

This document covers the fundamentals of serial communications, including the differences between serial and parallel communication, synchronous and asynchronous methods, and various protocols such as UART, SPI, and I2C. It discusses the advantages and disadvantages of different communication methods, error detection techniques, and software structures for handling asynchronous communication. Additionally, it provides examples of practical applications, such as the Voyager spacecraft, and includes details on implementing queues for data transmission.

Uploaded by

faris.banihani
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Lecture10_SerialCommunication

This document covers the fundamentals of serial communications, including the differences between serial and parallel communication, synchronous and asynchronous methods, and various protocols such as UART, SPI, and I2C. It discusses the advantages and disadvantages of different communication methods, error detection techniques, and software structures for handling asynchronous communication. Additionally, it provides examples of practical applications, such as the Voyager spacecraft, and includes details on implementing queues for data transmission.

Uploaded by

faris.banihani
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 60

Serial Communications

© 2021 Arm
Learning Objectives
At the end of this lecture, you should be able to:
• Outline the concepts of both serial and parallel communication and give examples of
their applications.
• Explain the difference between synchronous and asynchronous serial communication.
• Compare serial and parallel communication including their advantages and
disadvantages.
• Outline the difference between synchronous half-duplex and full-duplex serial buses
• Describe UART and its communication protocol.
• Describe SPI communication protocol.
• Describe I2C communication protocol.

2 © 2021 Arm
Overview
• Serial communications
• Concepts
• Tools
• Software: polling, interrupts, and buffering

• Protocols:
• UART
• SPI
• I2C

3 © 2021 Arm
Why Communicate Serially?
• Native word size is multi-bit (8, 16, 32, etc.)

• Often it’s not feasible to support sending all the word’s bits at the same time
• Cost and weight: more wires needed, larger connectors needed
• Mechanical reliability: more wires => more connector contacts to fail
• Timing Complexity: some bits may arrive later than others due to variations in capacitance and
resistance across conductors
• Circuit complexity and power: may not want to have 16 different radio transmitters + receivers in the
system

4 © 2021 Arm
Example System: Voyager Spacecraft

• Launched in 1977
• Constraints: Reliability, power, size, weight, reliability, reliability, etc.
• “Uplink communications are via S-band (16-bits/sec command rate) while an X-band transmitter provides
downlink telemetry at 160 bits/sec normally and 1.4kbps for playback of high-rate plasma wave data. All
data are transmitted from and received at the spacecraft via the 3.7 meters high-gain antenna (HGA).”
http://voyager.jpl.nasa.gov/spacecraft/index.html
• Uplink – to spacecraft
• Downlink – from spacecraft
5 © 2021 Arm
Example System

• Dedicated point-to-point connections


• Parallel data lines, read and write lines between MCU and each peripheral
• Fast, allows simultaneous transfers
• Requires many connections, PCB area, scales badly

6 © 2021 Arm
Parallel Buses

• All devices use buses to share data, read, and write signals
• MCU uses individual select lines to address each peripheral
• MCU requires fewer pins for data, but still one per data bit
• MCU can communicate with only one peripheral at a time

7 © 2021 Arm
Synchronous Serial Data Transmission

Transmitting Device Receiving Device

Clock
Serial Data
Data Sampling Time at Receiver
• Use shift registers and a clock signal to convert between serial and parallel formats
• Synchronous: an explicit clock signal is along with the data signal

8 © 2021 Arm
Synchronous Full-Duplex Serial Data Bus

• Now can use two serial data lines - one for reading, one for writing.
• Allows simultaneous send and receive full-duplex communication

9 © 2021 Arm
Synchronous Half-Duplex Serial Data Bus

• Share the serial data line


• Doesn’t allow simultaneous send and receive - is half-duplex communication

10 © 2021 Arm
Asynchronous Serial Communication
Data bits
Start bit Stop bit

Time Zero

Tbit*1.5

Tbit*2.5

Tbit*3.5

Tbit*4.5

Tbit*5.5

Tbit*6.5

Tbit*7.5

Tbit*8.5

Tbit*9.5
Data Sampling
Time at Receiver

• Eliminate the clock line!


• Transmitter and receiver must generate clock locally
• Transmitter must add start bit (always same value) to indicate start of each data frame
• Receiver detects leading edge of start bit, then uses it as a timing reference for sampling
data line to extract each data bit N at time Tbit*(N+1.5)
• Stop bit is also used to detect some timing errors
11 © 2021 Arm
Serial Communication Specifics
Start bit Data bits Stop bit
• Data frame fields
• Start bit (one bit)
• Data (LSB first or MSB, and Message
size – 7, 8, 9 bits)
• Optional parity bit is used to make total number of ones in data even or odd
• Stop bit (one or two bits)
• All devices must use the same communications parameters
• E.g. communication speed (300 baud, 600, 1200, 2400, 9600, 14400, 19200, etc.)
• Sophisticated network protocols have more information in each data frame
• Medium access control – when multiple nodes are on bus, they must arbitrate for permission to transmit
• Addressing information – for which node is this message intended?
• Larger data payload
• Stronger error detection or error correction information
• Request for immediate response (“in-frame”)

12 © 2021 Arm
Error Detection
• Can send additional information to verify data was received correctly
• Need to specify which parity to expect: even, odd or none.
• Parity bit is set so that total number of “1” bits in data and parity is even (for even
parity) or odd (for odd parity)
• 01110111 has 6 “1” bits, so parity bit will be 1 for odd parity, 0 for even parity
• 01100111 has 5 “1” bits, so parity bit will be 0 for odd parity, 1 for even parity
• Single parity bit detects if 1, 3, 5, 7 or 9 bits are corrupted, but doesn’t detect an even
number of corrupted bits
• Stronger error detection codes (e.g. Cyclic Redundancy Check) exist and use multiple
bits (e.g. 8, 16), and can detect many more corruptions.
• Used for CAN, USB, Ethernet, Bluetooth, etc.

13 © 2021 Arm
Tools for Serial Communications Development

• Tedious and slow to debug serial protocols • Saelae 8-Channel Logic Analyzer
with just an oscilloscope • $150 (www.saelae.com)
• Plugs into PC’s USB port
• Instead use a logic analyzer to decode bus • Decodes SPI, asynchronous serial, I2C, 1-Wire,
traffic CAN, etc.
• Worth its weight in gold! • Build your own: with Logic Sniffer or
related open-source project
14 © 2021 Arm
Software Structure –
Handling asynchronous
Communication

© 2021 Arm
Software Structure
• Communication is asynchronous to program
• Don’t know what code the program will be executing …
▪ when the next item arrives
▪ when current outgoing item completes transmission
▪ when an error occurs
• Need to synchronize between program and serial communication interface somehow
• Options
• Polling
▪ Wait until data is available
▪ Simple but inefficient of processor time
• Interrupt
▪ CPU interrupts program when data is available
▪ Efficient, but more complex

16 © 2021 Arm
Serial Communications and Interrupts
Main Program or
• Want to provide multiple threads of control in the other threads
program
• Main program (and subroutines it calls)
send_string get_string
• Transmit ISR – executes when serial interface is ready to send
another character
• Receive ISR – executes when serial interface receives a
character
• Error ISR(s) – execute if an error occurs

• Need a way of buffering information between tx_isr rx_isr


threads
• Solution: circular queue with head and tail pointers Serial
• One for tx, one for rx Interface

17 © 2021 Arm
Code to Implement Queues newer
older
data data
• Enqueue at tail: tail is the index of the next free entry
• Dequeue from head: head is the index of the item to remove
• Queue size is initialized and stored in size
• One queue per direction read data write data
• tx ISR unloads tx_q from head to tail
• rx ISR loads rx_q
• Other threads (e.g. main) load tx_q and unload rx_q send_string get_string

• Need to wrap pointer at end of buffer to make it circular,


• Use % (modulus, remainder) operator if queue size is not power of two
• Use & (bitwise and) if queue size is a power of two rx_isr
tx_isr
• Queue is empty if tail == head
Serial
• Queue is full if (tail + 1) % size == head Interface

18 © 2021 Arm
Defining the Queues
typedef struct {
uint8_t *data; //!< Array of data, stored on the heap.
uint32_t head; //!< Index in the array of the oldest element.
uint32_t tail; //!< Index in the array of the youngest element.
uint32_t size; //!< Size of the data array.
} Queue;

19 © 2021 Arm
Initialization and Status Inquiries
int queue_init(Queue *queue, uint32_t size) {
queue->data = (uint8_t*)malloc(sizeof(uint8_t) * size);
queue->head = 0;
queue->tail = 0;
queue->size = size;

// If malloc returns NULL (0) the allocation has failed.


return queue->data != 0;
}
int queue_is_full(Queue *queue) {
return ((queue->tail + 1) % queue->size) == queue->head;
}
int queue_is_empty(Queue *queue) {
return queue->tail == queue->head;
}
20 © 2021 Arm
Enqueue and Dequeue
int queue_enqueue(Queue *queue, uint8_t item) {
if (!queue_is_full(queue)) {
queue->data[queue->tail++] = item;
queue->tail %= queue->size;
return 1;
} else {
return 0;
}
}
int queue_dequeue(Queue *queue, uint8_t *item) {
if (!queue_is_empty(queue)) {
*item = queue->data[queue->head++];
queue->head %= queue->size;
return 1;
} else {
return 0;
}
}
21 © 2021 Arm
Using the Queues
• Sending data:

queue_enqueue(…, c)

• Receiving data:

queue_dequeue(…, &c)

22 © 2021 Arm
Software Structure –
Parsing Messages

© 2021 Arm
Decoding Messages
• Two types of messages
• Actual binary data sent
– First identify message type
– Second, based on this message type, copy binary data from message fields into variables
▪ May need to use pointers and casting to get code to translate formats correctly and safely
• ASCII text characters representing data sent
▪ First identify message type
▪ Second, based on this message type, translate (parse) the data from the ASCII message format into a binary format
▪ Third, copy the binary data into variables

24 © 2021 Arm
Example Binary Serial Data: TSIP

switch (id) { Report Packet (0x84) Data Structure


case 0x84: Type sizeof(Type) Item Units
lat = *((double *)(&msg[0]));
lon = *((double *)(&msg[8])); Double 8 Latitude Radians; + for
alt = *((double *)(&msg[16])); north, - for south
clb = *((double *)(&msg[24]));
tof = *((float *)(&msg[32])); Double 8 Lonitude Radians; + for east,
break; - for west
case 0x4A: …
Double 8 Altitude Meters
default: Double 8 Clock Bias Meters
break;
} Single 4 Time-of-fix Seconds

25 © 2021 Arm
Example ASCII Serial Data: NMEA-0183
$IDMSG,D1,D2,D3,D4,…,Dn*CS\r\n
• $ denotes the start of a message
• ID is a two letter mnemonic to describe the source of data, e.g. GP signifies GPS
• MSG is a three letter mnemonic to describe the message content.
• Commas are used to delaminate the data fields.
• Dn represents each of the data fields.
• * is used to separate the data from the checksum.
• CS contains two ASCII characters representing the hex value of the checksum.
• \r\n is the carriage return character followed by the new line character to denote the
end of a message.

26 © 2021 Arm
State Machine for Parsing NMEA-0183
Any char. except *, \r or \n
Start $ Append char to buf.
Append char to buf. Talker + Inc. counter
*, \r or \n, Sentence
non-text, or Type
buf==$SDDBT, $VWVHW, or $YXXDR
counter>6 Enqueue all chars. from buf

/r or /n
Sentence
Body Any char. except *
Enqueue char
*
Enqueue char

Checksum
1
Any char.
Save as checksum1
Checksum
2
Any char.
27 © 2021 Arm Save as checksum2
Parsing
switch (parser_state) {
case TALKER_SENTENCE_TYPE:
switch (msg[i]) {
‘*’:
‘\r’:
‘\n’:
parser_state = START;
break;
default:
if (Is_Not_Character(msg[i]) || n>6) {
parser_state = START;
} else {
buf[n++] = msg[i];
}
break;
}
if ((n==6) & … ){
parser_state = SENTENCE_BODY;
}
break;
case SENTENCE_BODY:
break;

28 © 2021 Arm
Asynchronous serial
(UART)
Communications

© 2021 Arm
Transmitter Basics
Data
bits

Data Sampling

Time Zero
Time at Receiver

Tbit
Tbit

Tbit

Tbit

Tbit

Tbit

Tbit

Tbit

Tbit

Tbit

Tbit
• If no data to send, keep sending 1 (stop bit) – idle line
• When there is a data word to send
• Send a 0 (start bit) to indicate the start of a word
• Send each data bit in the word (use a shift register for the transmit buffer)
• Send a 1 (stop bit) to indicate the end of the word

30 © 2021 Arm
Receiver Basics
Data
bits

Data Sampling

Zero
Time

Tbit*10.5
Tbit*1.5

Tbit*2.5

Tbit*3.5

Tbit*4.5

Tbit*5.5

Tbit*6.5

Tbit*7.5

Tbit*8.5

Tbit*9.5
Time at
Receiver

• Wait for a falling edge (beginning of a Start bit)


• Then wait ½ bit time
• Do the following for as many data bits in the word
▪ Wait 1 bit time
▪ Read the data bit and shift it into a receive buffer (shift register)
• Wait 1 bit time
• Read the bit
▪ if 1 (Stop bit), then OK
▪ if 0, there’s a problem!

31 © 2021 Arm
For this to work…
• Transmitter and receiver must agree on several things (protocol)
• Order of data bits
• Number of data bits
• What a start bit is (1 or 0)
• What a stop bit is (1 or 0)
• How long a bit lasts
▪ Transmitter and receiver clocks must be reasonably close, since the only timing reference is the start of the start bit

32 © 2021 Arm
Input Data Oversampling

• When receiving, UART oversamples incoming data line


• Extra samples allow voting, improving noise immunity
• Better synchronization to incoming data, improving noise immunity

• Configurable oversampling from 8x to 32x


• Put desired oversampling factor minus one into SCB_CTRL, SCB_OVS bits.

33 © 2021 Arm
Baud Rate
• Need to divide high frequency clock down to desired baud rate * oversampling factor

• Example
• 24MHz -> 4800 baud with 16x oversampling
• Division factor = 24E6/(4800*16) = 312.5. Must round to closest integer value ( 312 or 313), will have a
slight frequency error.

34 © 2021 Arm
Using the UART
• When can we transmit? • When can we receive a byte?
• Transmit peripheral must be ready for data • Receive peripheral must have data
• Can poll the status register • Can poll the status register
• Or we can use an interrupt, in which case we • Or we can use an interrupt, and again we will
will need to queue up data need to queue the data

35 © 2021 Arm
Software for Polled Serial Comm.
void test_polled() {
uart_init(9600);
uart_enable();

while(1) {
uart_tx(uart_rx()); // echoes the received character back
}
}

36 © 2021 Arm
Example Receiver: Display Data on LCD
line = col = 0;
while (1) {
c = uart_rx();
lcd_set_cursor(col, line);
lcd_put_char(c);
col++;
if (col > 7) {
col = 0;
line++;
if (line > 1) {
line = 0;
}
}
}
37 © 2021 Arm
Software for Interrupt-Driven Serial Comm.
• Use interrupts

• First, initialize peripheral to generate interrupts

• Second, create single ISR with for the receive callback

• Third, enable the peripheral

38 © 2021 Arm
Interrupt Handler
Queue rx_queue;
void uart_rx_isr(uint8_t rx) {
// Store the received character
queue_enqueue(&rx_queue, rx);
}
int main() {
queue_init(&rx_queue, 128);
uart_init(9600);
uart_set_rx_callback(uart_rx_isr);
uart_enable();

}
39 © 2021 Arm
USB to UART Interface

• PCs haven’t had external asynchronous serial interfaces for a while, so how do we
communicate with a UART? USB UART

TX RX
D+ / D- USB to
PC UART MCU
bridge
• USB to UART interface RX TX
• USB connection to PC
• Logic level (0-3.3V) to microcontroller’s UART (not RS232 voltage levels)
• USB01A USB to serial adapter
• http://www.pololu.com/catalog/product/391
• Can also supply 5V, 3.3V from USB

40 © 2021 Arm
Building on Asynchronous Comm.
• Problem #1
• Logic-level signals (0 to 1.65V, 1.65V to 3.3V) are sensitive to noise and signal degradation

• Problem #2
• Point-to-point topology does not support a large number of nodes well
▪ Need a dedicated wire to send information from one device to another
▪ Need a UART channel for each device the MCU needs to talk to
▪ Single transmitter, single receiver per data wire

41 © 2021 Arm
Solution to Noise: Higher Voltages
• Use higher voltages to improve noise margin:
+3 V to +15 V, -3 V to -15 V

• Example IC (Maxim MAX3232) uses charge pumps to generate higher voltages from
3.3V supply rail

42 © 2021 Arm
Solution to Noise: Differential Signaling

Data into transmitter

Data out of transmitter, on bus

Data out of receiver

• Use differential signaling


• Send two signals: Buffered data (A), buffered complement of data (B)
• Receiver compares the two signals to determine if data is a one (A > B) or a zero (B > A)

43 © 2021 Arm
Solutions to Poor Scaling
• Approaches
• Allow one transmitter to drive multiple receivers (multi-drop)
• Connect all transmitters and all receivers to same data line (multi-point network). Need to add a
medium access control technique so all nodes can share the wire

• Example Protocols
• RS-232: higher voltages, point-to-point
• RS-422: higher voltages, differential data transmission, multi-drop
• RS-485: higher voltages, multi-point

44 © 2021 Arm
SPI Communications

© 2021 Arm
Hardware Architecture
• All chips share bus signals
• Clock SCK
• Data lines MOSI (master out, slave in) and MISO
(master in, slave out)

• Each peripheral has its own chip select line


(CS)
• Master (MCU) asserts the CS line of only the
peripheral it’s communicating with

46 © 2021 Arm
Serial Data Transmission

Transmitting Device Receiving Device

• Use shift registers and a clock signal to convert between serial and parallel formats
• Synchronous: an explicit clock signal is along with the data signal

47 © 2021 Arm
SPI Example: Secure Digital Card Access
• SD cards have two CMD / CLK /
GND VDD SCLK
communication modes DAT3 / DI GND DAT0/
• Native 4-bit CS DO
DAT2 /
• Legacy SPI 1-bit X DAT1/
• VDD from 2.7 V to 3.6 V X
• CS: Chip Select (active-LOW)

• Host sends a six-byte command packet to card


• Index, argument, CRC
• Host reads bytes from card until card signals it is ready
• Card returns
▪ 0xff while busy
▪ 0x00 when ready without errors
▪ 0x01-0x7f when error has occurred

48 © 2021 Arm
I2C Communications

© 2021 Arm
I2C Bus Overview
• “Inter-Integrated Circuit” bus
• Multiple devices connected by a shared serial bus
• Bus is typically controlled by master device, subordinates respond when addressed
• I2C bus has two signal lines
• SCL: Serial clock
• SDA: Serial data
• Full details available in “The I2C-bus Specification”

Author: Colin M.L. Burnett, Source: Wikimedia

50 © 2021 Arm
I2C Bus Connections

Author: Colin M.L. Burnett, Source: Wikimedia

• Resistors pull up lines to VDD

• Open-drain transistors pull lines down to ground

• Master generates SCL clock signal


• Can range up to 400 kHz, 1MHz, or more

51 © 2021 Arm
Master Writing Data to Subordinate

Start
ACK
Write ACK
Address Data
Repeated
Start

52 © 2021 Arm
Master Reading Data from Subordinate

SDA

SCL

Start Stop
ACK
Read ACK NACK
Address Data Data

53 © 2021 Arm
I2C Addressing
• Each device (IC) has seven-bit address
• Different types of device have different default addresses
• Sometimes can select a secondary default address by tying a device pin to a different logic level

• What if we treat the first byte of data as a register address?


• Can specify registers within a given device: 8 bits

54 © 2021 Arm
Enabling i2c
void temperature_init(void) {
i2c_init();
i2c_enable();
}

void temperature_enable(void) {
// Start conversion.
i2c_start();
i2c_tx(subordinate_ADDRESS | WRITE);
i2c_tx(START_CONVERT_T);
i2c_stop();
}
55 © 2021 Arm
Reading 12 bits from a temperature sensor
float temperature_read(void) {
short temp;
i2c_start();
i2c_tx(subordinate_ADDRESS | WRITE);
i2c_tx(READ_TEMPERATURE);
i2c_start();
i2c_tx(subordinate_ADDRESS | READ);
temp = i2c_rx() << 8;
i2c_ack();
temp |= i2c_rx();
i2c_nack();
i2c_stop();
// Sign extend from 16-bit to 12-bit.
temp >>= 4;
// Convert from fixed-point to floating point.
return temp / (float)16;
56
} © 2021 Arm
PROTOCOL COMPARISON

57 © 2021 Arm
Factors to Consider
• How fast can the data get through?
• Depends on raw bit rate, protocol overhead in packet
• How many hardware signals do we need?
• May need clock line, chip select lines, etc.
• How do we connect multiple devices (topology)?
• Dedicated link and hardware per device - point-to-point
• One bus for manager transmit/subordinate receive, one bus for subordinate transmit/manager receive
• All transmitters and receivers connected to same bus – multi-point

• How do we address a target device?


• Discrete hardware signal (chip select line)
• Address embedded in packet, decoded internally by receiver
• How do these factors change as we add more devices?

58 © 2021 Arm
Protocol Trade-Offs
Protocol Speed Signals Req. for Bidirectional Device Addressing Topology
Communication with N devices

UART (Point to Fast – Tens of Mbit/s 2*N (TxD, RxD) None Point-to-point full
Point) duplex
UART Fast – Tens of Mbit/s 2 (TxD, RxD) Added by user in Multi-drop
(Multi-drop) software
SPI Fast – Tens of Mbit/s 3+N for SCLK, MOSI, MISO, and Hardware chip select Multi-point
one SS per device signal per device full-duplex,
multi-drop
half-duplex buses
I2C Moderate – 100kbit/s, 400 2 (SCL, SDA) In packet Multi-point
kbit/s, 1Mbit/s, 3.4Mbit/s. half-duplex bus
Packet overhead.

59 © 2021 Arm
The Arm trademarks featured in this presentation are registered
trademarks or trademarks of Arm Limited (or its subsidiaries) in
the US and/or elsewhere. All rights reserved. All other marks
featured may be trademarks of their respective owners.

www.arm.com/company/policies/trademarks

© 2021 Arm

You might also like