Microcontrollers and Interfacing Week 10 Serial communication with devices: Serial Peripheral Interconnect (SPI) and Inter-Integrated Circuit (I 2 C) protocols College of Information Science and Engineering Ritsumeikan University 1
2 this week history of board-level serial communications I 2 C: topology, messages SPI: topology, data exchange example device: MCP3204 quad 12-bit ADC with SPI timing circuit layout the SPI library
3 history 1982: Philips was putting digital integrated circuits (ICs) into TV sets TV control (channel buttons on the front, etc.) had to communicate with the ICs ICs had to communicate with each other mini serial network developed: Inter-Integrated Circuit (I 2 C) protocol very good for configuring devices with control registers 1985: Motorola released a microcontroller based on the 68000 architecture needed a way to communicate with diverse, fast peripherals simplicity and speed were very important point-to-point protocol developed: Serial Peripheral Interface (SPI) very good for streaming data to/from external devices
4 I 2 C topology two wires: data (SDA) and clock (SCL) bus-based: devices send messages to each other message begins with destination device address specifies whether the message is a read or write operation master controls clock master and slave can both transmit to exhange a byte followed by an acknowledgement bit
5 I 2 C messages 127 devices can be connected each device has an address messages are sent to a specific device messages are byte oriented, and either read or write (not both) the protocol is half-duplex SCL SDA (bus claim) seven-bit slave address R/W ack 1 slave address and direction byte eight data bits ack N data bytes SCL SDA (bus release)
6 SPI topology simple case: one master, one slave master controls slave select and clock two data lines: MOSI (master slave) and MISO (slave master) data clocked on both lines every clock cycle stream of bits (no byte orientation), and protocol is full-duplex master slave SCK MOSI MISO SS serial clock master out, slave in master in, slave out slave select (active low) SCK MOSI MISO SS
7 SPI with multiple slaves common case: one master, a few slaves MISO is high-impedance (disconnected) unless slave selected only one slave select can be active at any given time needs additional slave select wire for each additional slave (can be avoided with shift registers, binary decoders, etc.) master SCK serial clock MOSI master out, slave in MISO master in, slave out SS0 SS1 slave 0 slave 1 slave 2 slave 3 SS2 SCK SCK SCK SCK SS3 MOSI MOSI MOSI MOSI MISO MISO MISO MISO SS SS SS SS slave selects
8 SPI data exchange serial clock SCK slave select SS phase 0 = leading edge polarity 0 = idle low master out MOSI msb......... lsb master in MISO msb......... lsb SPI clock mode clock active (polarity, phase) idles edge 0 (0, 0) low leading (rising) 1 (0, 1) low trailing (falling) 2 (1, 0) high leading (falling) 3 (1, 1) high trailing (rising)
9 SPI example: MCP3204 4-channel, 12-bit A/D converter V DD 5 V power supply DGND 0 V digital ground AGND 0 V analogue ground CH0 CH1 CH2 CH3 NC NC DGND 1 2 3 4 5 6 7 MCP3204 14 13 12 11 10 9 8 V DD V REF AGND CLK D OUT D IN CS/SHDN V REF reference voltage, sets the upper limit of input voltage (corresponding to the maximum digital A/D output value) CH0 CH4 the four analogue input channels CLK SPI serial clock input D IN SPI serial data input (equivalent to MOSI) D OUT SPI serial data output (equivalent to MISO) CS SPI active-low chip select (equivalent to SS)
10 SPI example timing CS MCU latches data from A/D converter on rising edges of SCLK SCLK 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 D IN Data is clocked out of A/D converter on falling edges SGL/ Start D2 D1 DO DIFF Don t Care D OUT HI-Z NULL BIT B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0 MCU Transmitted Data (Aligned with falling edge of clock) MCU Received Data (Aligned with rising edge of clock) Start Bit 0 0 0 0 0 1 SGL/ D2 DIFF D1 DO X X X X X X X X X X X X X X??????????? 0 (Null) B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0 X = Don t Care Bits Data stored into MCU receive register after transmission of first 8 bits Data stored into MCU receive register after transmission of second 8 bits Data stored into MCU receive register after transmission of last 8 bits
11 SPI example circuit 5V SCK (13) serial clock V DD SCK V REF CH0 10k MISO (12) master in, slave out MISO CH1 MOSI (11) master out, slave in MOSI CH2 SS (10) Arduino GND slave select (active low) SS CH3 DGND AGND MCP3204
12 SPI example layout Pin 1
13 the SPI library Arduino has hardware support for SPI, and a library for access import the SPI library #include <SPI.h> configure the SPI library void setup() { SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV4); // 4 MHz SPI.setDataMode(SPI_MODE0); // idle low, leading edge SPI.setBitOrder(MSBFIRST); } use the SPI library unsigned char misovalue = SPI.transfer(mosiValue); (performs full-duplex exchange of 8 bits)
14 bit banging when no hardware support for SPI (or any other protocol) we can assign General-Purpose I/O pins to the needed signals implement the protocol manually, by writing/reading the pins this is known (informally) as bit banging SPI signals #define SSN 10 // slave select pin #define MOSI 11 // master out pin #define MISO 12 // master in pin #define SCK 13 // serial clock pin SPI configuration void setup() { pinmode(ssn, OUTPUT); digitalwrite(ssn, HIGH); // slave inactive pinmode(sck, OUTPUT); digitalwrite(sck, LOW); // clock idle pinmode(mosi, OUTPUT); pinmode(miso, INPUT); }
15 bit banging write a single bit to SPI device void sendbit(unsigned char bit) { digitalwrite(mosi, bit & 1); digitalwrite(sck, HIGH); digitalwrite(sck, LOW); } // value to write // clock data into device // clock idle read a single bit from SPI device int recvbit(void) { digitalwrite(sck, HIGH); int bit = digitalread(miso); digitalwrite(sck, LOW); return bit; } // clock don t care bit into device // result bit from device // clock idle
bit banging example transaction: perform A/D conversion int readadc(int channel) { digitalwrite(ssn, LOW); sendbit(1); sendbit(1); sendbit(channel >> 2); sendbit(channel >> 1); sendbit(channel); sendbit(0); sendbit(0); // slave select active // start bit // single-ended mode // ms bit // ls bit // discard empty result bit // discard null result bit int advalue = 0; for (int i= 0; i < 12; ++i) advalue = (advalue << 1) + recvbit(); } digitalwrite(ssn, HIGH); return advalue; K // slave select inactive 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Data is clocked out of A/D converter on falling edges SGL/ Start D2 D1 DO DIFF Don t Care NULL BIT B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0 16
17 next week quick review of other devices displays sensors physical interfaces networking project suggestions some are complete projects some require connecting a few pieces together