Aim:
The Serial Peripheral Interface Bus (SPI) interface is used for communication between multiple devices over short distances, and at high speed.
Typically there is a single "master" device, which initiates communications and supplies the clock which controls the data transfer rate. There can be one or more slaves. For more than one slave, each one has its own "slave select" signal, described later.
Description:
SPI signals
In a full-blown SPI system you will have four signal lines:
- Master Out, Slave In (MOSI) - which is the data going from the master to the slave
- Master In, Slave Out (MISO) - which is the data going from the slave to the master
- Serial Clock (SCK) - when this toggles both the master and the slave sample the next bit
- Slave Select (SS) - this tells a particular slave to go "active"
When multiple slaves are connected to the MISO signal they are expected to tri-state (keep at high impedance) that MISO line until they are selected by Slave Select being asserted. Normally Slave Select (SS) goes low to assert it. That is, it is active low. Once a particular slave is selected it should configure the MISO line as an output so it can send data to the master.
This image shows the way that data is exchanged as one byte is sent:
Note that three signals are outputs from the master (MOSI, SCK, SS) and one is an input (MISO).
Wiring for output-only SPI
The above code (which sends only) might be used to drive an output serial shift register. These are output-only devices, so we don't need to worry about any incoming data. In their case the SS pin might be called the "store" or "latch" pin.
Examples of this are the 74HC595 serial shift register, and various LED strips, just to mention a couple. For example, this 64 pixel LED display driven by a MAX7219 chip:
- DIN (Data In) is MOSI (Master Out, Slave In)
- CS (Chip Select) is SS (Slave Select)
- CLK (Clock) is SCK (Serial Clock)
Most boards will follow a similar pattern. Sometimes DIN is just DI (Data In).
Here is another example, this time a 7-segment LED display board (also based on the MAX7219 chip):
Block Diagram
Schematic
Code
// *******************************************************
// Project: Interfacing SPI-MAX72xx using PIC18F4520
// Author: Hack Projects India
// Module description: Operate DAC
// *******************************************************
#include <p18f4520.h>
#include <delays.h>
#pragma config OSC=HS, FCMEN=ON, WDT=OFF, IESO=OFF, XINST=OFF, LVP=OFF
#define cs PORTAbits.RA5
void display(int , int);
void delay(unsigned int);
void main(void)
{
TRISAbits.TRISA5 = 0; //used for Chip Select function; configured as output
TRISCbits.TRISC3 = 0; //used for SCK; configured as output
TRISCbits.TRISC5 = 0; //used for transferring serial data; configured as output
//SPI
SSPSTAT = 0xC0; //SSPSTAT=11000000 i.e. configure SPI settings
SSPCON1 = 0x20; //SSPCON1=00100000 Enables serial port and configures SCK, SDO and SDI as serial port pins & clock=FOSC/4
display(0x0B,0X07); //scanlimit(digits 0-7)
display(0x09,0X00); //decode mode off
display(0x0A,0X0F); //intensity highest
display(0x0C,0X01); //shutdown mode off
display(0x0F,0X00); //test mode off
display(1,'9');
display(2,'8');
display(3,'7');
display(4,'6');
display(5,'5');
display(6,'4');
display(7,'3');
display(8,'2');
while(1);
}
void display(int addr, int value)
{
cs = 0; //enable MAX7221 to receive new value
SSPBUF = addr; //sending the address of digit serially
while(!SSPSTATbits.BF); //wait until the address is sent
switch(value)
{
case '0' : value = 126; break;
case '1' : value = 48; break;
case '2' : value = 109; break;
case '3' : value = 121; break;
case '4' : value = 51; break;
case '5' : value = 91; break;
case '6' : value = 95; break;
case '7' : value = 112; break;
case '8' : value = 127; break;
case '9' : value = 115; break;
case 't' : value = 15; break;
case 'P' : value = 103; break;
case 'b' : value = 31; break;
case 'd' : value = 61; break;
}
SSPBUF = value; //sending the value which is to be displayed
while(!SSPSTATbits.BF); //wait until the value is sent
cs = 1; //disable MAX7221 to receive any new value
}
void delay(unsigned int time) //delay function
{
unsigned int i,j;
for(i=0;i<time;i++)
for(j=0;j<120;j++);
}
Downloads:
The code was compiled in Keil uvision4 and simulation was made in Proteus v7.7.
To download code and proteus simulation click here.
Further Reading suggestions:
You may also like,
- Interfacing keypad with PIC
- nterfacing DAC with PIC
- Interfacing with UART of PIC controller
- PIC Displaying Custom Characters on LCD
- PIC Graphical LCD
- RTC interfacing using I2C in PIC
- Interfacing ultrasonic sensor with PIC
- Interfacing GPS Modu with PIC
- Interfacing GSM Module with PIC
- Interfacing PWM in PIC
- Interfacing ADC with PIC
- Scrolling string on LCD using PIC
- Interfacing keypad with PIC
- nterfacing DAC with PIC
- Interfacing with UART of PIC controller
- PIC Displaying Custom Characters on LCD
- PIC Graphical LCD
- RTC interfacing using I2C in PIC
- Interfacing ultrasonic sensor with PIC
- Interfacing GPS Modu with PIC
- Interfacing GSM Module with PIC
- Interfacing PWM in PIC
- Interfacing ADC with PIC
- Scrolling string on LCD using PIC
No comments:
Post a Comment