Introduction
The Serial Peripheral Interface (SPI) is one of the popular embedded serial communications widely supported by many of today’s chip manufacture and it considered as one of the fastest serial data transfer interface for the embedded system. Because of its special in/out register configuration, the SPI master device could transfer its data and at the same time it receive a data from the SPI slave device with the clock speed as high as 10 MHz. Beside its superior data transfer speed; SPI also use a very simple data transfer protocol compared to the other serial data transfer methods. When the SPI master device want to send the data to the SPI slave device then the SPI master will just simply shifting its own data through a special 8-bits register and at the same time the SPI master will receive the data from the SPI slave into the same register as shown on this following picture.
With this circular shift register connection between the SPI master and the SPI slave devices, the complete data transfer from both devices will be accomplished in just 8 clock cycles. This means the SPI devices only need about 0.8 us to complete transfer the 8-bit data if we use 10 MHz clock. One of the drawbacks using the SPI especially when we use multiple SPI slave device is the SPI slave could not initiate sending its own data to the SPI master device, all the data transfer initiation is always come from the SPI master. The SPI master device has to poll each of the SPI slave devices to know whether the SPI slave device has a data to be sent to the SPI master device or not.
Polling the entire SPI slave devices will eventually consumed the SPI master resources when the SPI slave devices to be polled increase, therefore some of the SPI slave device is equipped with the interrupt pin to notify the SPI master device that it has a data to be read.
The PIC18F458 Microcontroller
On this tutorial I will use the Microchip PIC18F458 microcontroller, this microcontroller is one of my favorite 8-bit 40-pins PIC18 microcontroller families members as it is equipped with sophisticated advanced peripheral inside such as ADC, USART, ECCP (Enhanced Capture/Compare/PWM), SPI, I2C . With 32K bytes flash ram and equipped with the build in circuit debug, this 8-bit 20-pins microcontroller is a perfect choice for serious embedded application or just for hobbyist’s project.
The PIC18F458 microcontroller SPI peripheral support both master and slave mode but on this tutorial we will only exposing the PIC18F458 SPI master mode.we will be using 74LS395 shift register ic To expand the serial bit into parallel configuration.
As 74LS395 is only 4 bit shift register so we will be able to see only four Least Significant bits. you can use 74LS595 to display all 8 bits if you want to, but for now we will be working with 74LS395 4 bit shift register.
74LS395 Pin Configuration And Function Table
Hardware Connection
Programming The PIC:-
SOFTWARE CODE SPI TEST .C
#pragma config OSC = HS, OSCS = OFF
#pragma config PWRT= OFF , BOR=ON, BORV = 45
#pragma config WDT = OFF
#pragma config DEBUG = OFF ,LVP =OFF , STVR =OFF // CONFIGURATION BIT SETTING
#include <p18f458.h>
void spi(unsigned char); //SPI Function To send the data
void delayMs(int x); // to generate some delay
void main() // main program starts here
{
SSPSTAT =0x40; // Configure SSPSTAT for transmission occur from idle to active clock and Buffer flag =0
SSPCON1=0x22; //Configure SSPCON1 for ENABLE SERIAL PORT
// and disable general I/O pin ,, SPI master clock= Fosc/64
TRISC=0; //Configure PORT C as output ,,
// we are only sending the data so we do't need to set SPI pin as input
while(1) // loop for ever so that led keep repeating that pattern
{
spi(0x01); // send 01 hex to the SPI port it will glow the first led
delayMs(1000); // wait for approximate 1sec ,
//if we do't give the delay then led will flash too fast that
// we can't even know when it glow and when it off
spi(0x02); //send 02 hex to the SPI port it will glow the send led ,
//if you want to glow both led same time send 03 hex and so on
delayMs(1000); // wait for 1 sec
}
}
void spi(unsigned char myData)
{
SSPBUF = myData; // put the data in the SSPBUF register which going to be send
while(!SSPSTATbits.BF); // wait until the all bits sended
}
void delayMs(int x) // a general delay function
{
int i;
for (x ;x>0;x--)
{
for (i=0;i<=110;i++);
}
}
DOWNLOAD MPLAB PROJECT , Source Code and Firmware
How to Decide SSPSTAT and SSPCON1 register value
As 74LS395 is only 4 bit shift register so we will be able to see only four Least Significant bits. you can use 74LS595 to display all 8 bits if you want to, but for now we will be working with 74LS395 4 bit shift register.
74LS395 Pin Configuration And Function Table
Hardware Connection
Programming The PIC:-
SOFTWARE CODE SPI TEST .C
#pragma config OSC = HS, OSCS = OFF
#pragma config PWRT= OFF , BOR=ON, BORV = 45
#pragma config WDT = OFF
#pragma config DEBUG = OFF ,LVP =OFF , STVR =OFF // CONFIGURATION BIT SETTING
#include <p18f458.h>
void spi(unsigned char); //SPI Function To send the data
void delayMs(int x); // to generate some delay
void main() // main program starts here
{
SSPSTAT =0x40; // Configure SSPSTAT for transmission occur from idle to active clock and Buffer flag =0
SSPCON1=0x22; //Configure SSPCON1 for ENABLE SERIAL PORT
// and disable general I/O pin ,, SPI master clock= Fosc/64
TRISC=0; //Configure PORT C as output ,,
// we are only sending the data so we do't need to set SPI pin as input
while(1) // loop for ever so that led keep repeating that pattern
{
spi(0x01); // send 01 hex to the SPI port it will glow the first led
delayMs(1000); // wait for approximate 1sec ,
//if we do't give the delay then led will flash too fast that
// we can't even know when it glow and when it off
spi(0x02); //send 02 hex to the SPI port it will glow the send led ,
//if you want to glow both led same time send 03 hex and so on
delayMs(1000); // wait for 1 sec
}
}
void spi(unsigned char myData)
{
SSPBUF = myData; // put the data in the SSPBUF register which going to be send
while(!SSPSTATbits.BF); // wait until the all bits sended
}
void delayMs(int x) // a general delay function
{
int i;
for (x ;x>0;x--)
{
for (i=0;i<=110;i++);
}
}
DOWNLOAD MPLAB PROJECT , Source Code and Firmware
How to Decide SSPSTAT and SSPCON1 register value
how u make to drive 9 leds,74ls395 have only 4bit output?
ReplyDeletehi
ReplyDeletei m just driving only 4 led other 5 led are disconnected (no use)
but if you want to drive more led with only 4 output pins then use multiplexing
or use can also use 74ls595 with 8 output lines
Hi Dear
ReplyDeleteThanks for you kind information. I have varified its and it is 100% Working. It would be kind of u if u add spi read section as well.
hi
ReplyDeletewhat about in master slave mode and with transmit receive both enabled?
this does not work.
ReplyDeleteHI, can i know how do you use spi to communicate with another board? as I done the code, but my voltage isnt measuring is it possible to help me check my code?
ReplyDeletehi
ReplyDeletecould you please send the Proteus file as i tested the code in mikroC but the clock did not initialized and nothing is working!!!
Thank you
Hello
ReplyDeleteI am unable to understand
SSPSTAT =0x40; // Configure SSPSTAT for transmission occur from idle to active clock and Buffer flag =0
datasheet says if it,s bit CKE = 1 means active to idle, but you says idle to active. What am i not undurstanding.
Please explain