SPI communication between PICs

From Mech
Revision as of 03:34, 11 February 2009 by Kwang Sim (talk | contribs)
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Overview

SPI or Serial Peripheral Interface is a communication method that was once used to connect devices such as printers, cameras, scanners, etc. to a desktop computer. This function has largely been taken over by USB, but SPI can still be a useful communication tool for some applications. SPI runs using a master/slave set-up and can run in full duplex mode, meaning that signals can be transmitted between the master and the slave simultaneously. There is no standard communication protocol for SPI.

SPI is still used to control some peripheral devices and has some advantages over I2C (another type of serial data communication). SPI can communicate at much higher data rates than I2C. Furthermore, when multiple slaves are present, SPI requires no addressing to differentiate between these slaves. Compared to parallel buses, SPI has the additional benefit of requiring only simple wiring.


Peripheral devices that still use SPI:

• Converters (ADC and DAC)

• Memories (EEPROM and FLASH)

• Real Time Clocks (RTC)

• Sensors (temperature, pressure, etc.)

• Others (signal mixer, potentiometer, LCD controller, UART, CAN controller, USB controller, amplifier)


Basic Operation

SPI requires four lines, and is therefore often termed the “four wire” serial bus. These four lines are described in the table below.

Line Name Description
SCLK Serial Clock Output from master
MOSI/SIMO Master Output, Slave Input Output from master
MISO/SOMI Master Input, Slave Output Output from slave
SS Slave Select Output from master (active low)
Spi-diagram.png

The master, as its name suggests, controls all communication. By controlling the clock, the master decides when data is sent and received. Within each clock cycle a full duplex communication is carried out; each side sends and receives one bit of information. Because there is no standard communication protocol, the master can either send data or both send and receive data, depending on the needs of the application. Likewise, the slave can either receive data or both receive and send data back to the master.

Using the “Slave Select” line, the master chooses which slave with which to communicate. Note that more than one slave may be selected, simply by applying a logic low to the desired SS lines, as illustrated in the schematic diagram shown above. If a given slave is not selected (its SS is high) it disregards signals sent by the master.


References

SPI Background.www.totalphase.com

Serial Peripheral Interface. Www.wikipedia.org

mct.net

Circuit

Spi-circuit.jpg

see www.totalphase.com

Above shows the Master connected to three slaves. Each slave must be enabled through the slave select pin in order to communicate with the Master.

Spi.jpg

The two PICs can be wired directly by connecting these input and output pins of the diagram above.

Code

In the example below, the master reads an 8-bit value from the analog-to-digital converter and sends it to the slave via SPI. The slave reads the value and displays it on an LCD display.

Master Code:

#include <18f4520.h>
#fuses EC,NOLVP,NOWDT,NOPROTECT
#device ADC=8
#use delay(clock=40000000)

void main()
{
   int val;

   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_64);
   
   while(true) {
       val = read_adc();
       
       output_low(PIN_A5);
       delay_us(10);
       
       spi_write(val);
       
       delay_us(10);
       output_high(PIN_A5);
       
       delay_ms(10);
   }
}


Slave Code:

#include <18f4520.h>
#fuses EC,NOLVP,NOWDT,NOPROTECT
#use delay(clock=40000000)

#include <LCD.C>


#int_ssp
void message_receieved() {
    unsigned int val;
    val = spi_read();
    lcd_gotoxy(1, 1);
    printf(lcd_putc, "Pot at: %u   ", val);
}

void main()
{
   setup_spi(SPI_SLAVE | SPI_L_TO_H);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   
   lcd_init();
   
   while(true);
}


The CCS user manual

CCS forum