PIC to PIC SPI communication with DC motor control

PIC to PIC SPI communication with DC motor, In this pic microcontroller based project, we are using serial peripheral interface communication and controlling a direction of dc motor. I have already posted an article on spi communication using pic16F877A microcontroller. So this project is a practical application of SPI communication using two PIC16F877A microcontrollers. In this project, I have used two PIC16F877A microcontrollers, one microcontroller is used as a master and another microcontroller is used as a slave.  The master microcontroller sends commands to slave microcontroller.

Slave microcontroller receives these commands and takes action accordingly. DC motor is interfaced with slave microcontroller. The master microcontroller sends commands through push button to slave microcontroller through serial communication and slave microcontroller receive these commands through SPI protocol and rotate the motor in clockwise or anti-clockwise direction accordingly.  As I mentioned earlier, I have used two pic16f877a microcontrollers in this project. So let’s take a look at registers of PIC16F877A used for PIC TO PIC SPI communication.

PIC to PIC communication through SPI communication protocol

PIC16F877A microcontroller has one SPI module which can transmit and receive 8 bit simultaneously. PIC16F877A microcontroller can act either as a master or a slave.  Followings are the four pins use for SPI communication:

  • Serial Data Out (SDO) – RC5/SDO which is pin number 5 of PORTC
  • Serial Data In (SDI) – RC4/SDI/SDA which is pin number four of PORTC
  • Serial Clock (SCK) – RC3/SCK/SCL which is pin number three of PORTC
  • Slave Select (SS) – RA5/AN4/ which is pin number 5 of PORTA

Slave select pin is only used when we are using a microcontroller as a slave mode. Serial clock pin is always an output pin for a master microcontroller and input pin for a slave microcontroller.  SPI module has four registers and the fourth register is not accessible to programmers. SSCON and SSSTAT are control and status registers for the SPI module and SSPBUF is used for data buffer for data storage for reading and writing purpose.  You Can check the datasheet of pic16f877a microcontroller for more details about all bits of these 8 bits registers.

  • SPI module Control Register (SSPCON)
  • SPI moduleStatus Register (SSPSTAT)
  • SPI module Serial Receive/Transmit Buffer Register
    (SSPBUF)
  • SPI module Shift Register (SSPSR): This register is not accessible to programmers directly.

Connection diagram for Master and Slave with SPI module is shown below:

Master and SLAVE SPI connection

So we need to initialize corresponding control registers of one microcontroller as a master and another microcontroller as a slave. Let’s see how to initialize pic16f877a microcontroller as master and as a slave.

How to initialize pic16f877a microcontroller as master?

To initialize pic microcontroller as a master, we need to set the bits of status register and control register of SPI module. The master microcontroller can send the data any time to any slave. Because it always has control of SCK pin which is a clock pin.  So we must set RC3/SCK pin of PIC16F877A microcontroller as an output pin.  Following settings of control registers will initialize the pic16f877a microcontroller as a master.

TRISC.B5 = 0; // Set the Data out pin as a output pin                                                                                                
SSPSTAT.SMP=1;
SSPSTAT.CKE=0;
SSPCON.WCOL=0;
SSPCON.SSPOV=0;
SSPCON.SSPM3=0;
SSPCON.SSPM2=0;
SSPCON.SSPM1=0;
SSPCON.SSPM0=0;
SSPCON.SSPEN=1;                                                                                                                           SSPCON = 0b00100000;                                                                                                                                              TRISC.B3 = 0; //set the clock pin as output pin
TRISC.B4 = 1; // set the data in pin as input pin

How to initialize pic16f877a SPI module as a slave?

Similarly, we need to initialize the status and control register pins for slave mode selection. In this case, the SCK pin acts as an input pin. Because the clock signal is an input signal from a master.  Followings settings initialize the SPI module as a slave.

TRISC.B5 = 0;
SSPSTAT.SMP=1;
SSPSTAT.CKE=0;
SSPCON.WCOL=0;
SSPCON.SSPOV=0;
SSPCON.SSPM3=0;
SSPCON.SSPM2=1;
SSPCON.SSPM1=0;
SSPCON.SSPM0=1;
SSPCON.SSPEN=1;
TRIS.B4 = 1 
TRISC.B3 = 1; 

PIC to PIC communication through SPI module with DC motor control

SSPBUF buffer register is used to check to receive and send data.  Circuit diagram for PIC to PIC communication through SPI module with dc motor control is shown below. PIC to PIC communication through SPI module

For more details about the working check the video.

Code for Master SPI microcontroller

sbit swcw at PORTB.b0;
sbit swcw_direction at TRISB.b0;

sbit swccw at PORTA.b0;
sbit swccw_direction at TRISA.b0;

//outputs
sbit sck at PORTC.b3;
sbit sck_direction at TRISC.b3;

//outputs
sbit dt at PORTC.b5;
sbit dt_direction at TRISC.b5;

//constants
const char motorcw=0x01;
const char motorccw=0x02;
const char motoridle=0x03;

void main() {
//initialization
ANSEL=0x00;
ANSELH=0x00;
swccw=0;
swcw_direction=1;

swccw=0;
swccw_direction=1;

//Configure MSSP 3 registers
SSPSTAT.SMP=1;
SSPSTAT.CKE=0;
SSPCON.WCOL=0;
SSPCON.SSPOV=0;
SSPCON.SSPM3=0;
SSPCON.SSPM2=0;
SSPCON.SSPM1=0;
SSPCON.SSPM0=0;
SSPCON.SSPEN=1;

sck=0;
sck_direction=0;

dt=0;
dt_direction=0;

TRISC.RC4=0;
Delay_ms(50);

while(1){
if (swcw==1) {
SSPBUF=motorcw;
}
else{
if (swccw==1){
SSPBUF=motorccw;
}
else{
SSPBUF=motoridle;
}
}
}
}

Code for slave SPI  microcontroller

sbit sck at PORTC.b3;
sbit sck_direction at TRISC.b4;

sbit dt at PORTC.b4;
sbit dt_direction at TRISC.b4;


//outputs
sbit mcw at PORTD.b5;
sbit mcw_direction at TRISD.b5;

sbit mccw at PORTD.b7;
sbit mccw_direction at TRISD.b7;

//variables
char rcdata;

//constants
const char motorcw=0x01;
const char motorccw=0x02;
const char motoridle=0x03;

void main() {
//initialization
ANSEL=0x00;
ANSELH=0x00;

//Configure MSSP 3 registers
SSPSTAT.SMP=1;
SSPSTAT.CKE=0;
SSPCON.WCOL=0;
SSPCON.SSPOV=0;
SSPCON.SSPM3=0;
SSPCON.SSPM2=1;
SSPCON.SSPM1=0;
SSPCON.SSPM0=1;
SSPCON.SSPEN=1;

sck=0;
sck_direction=1;

dt=0;
dt_direction=1;

mcw=0;
mcw_direction=0;

mccw=0;
mccw_direction=0;
Delay_ms(50);

while(1){
rcdata=SSPBUF;
switch (rcdata){
case motorcw:
mcw=1;
mccw=0;
break;
case motorccw:
mcw=0;
mccw=1;
break;
case motoridle:
mcw=0;
mccw=0;
break;
}
}

}

You can check more pic microcontroller tutorials on this link.

Leave a Comment

shares