SPI Master
//----- SETUP SPI 1 -----
//Used for:
w_temp = SPI1BUF;
SPI1STAT = 0;
SPI1CON1 = 0b0000001100100001; //SPI in master mode (SPI1STATbits.SPIEN must be 0 to write to this register)
//Data is valid on the rising edge of the clock (Transmit occurs on transition from active to idle clock state)
//Clock low in idle bus state
SPI1CON1bits.PPRE1 = 1; //Prescallers 4:1 1:1 = 10MHz (max possible from this device)
SPI1CON1bits.PPRE0 = 0;
SPI1CON1bits.SPRE2 = 1;
SPI1CON1bits.SPRE1 = 1;
SPI1CON1bits.SPRE0 = 1;
SPI1CON2 = 0;
SPI1STATbits.SPIEN = 1; //Enable the port
SPI Slave
Initialise
//----- SETUP SPI 2 -----
//Used for:
SPI2BUF = 0;
IFS2bits.SPI2IF = 0; //Clear the Interrupt Flag
IEC2bits.SPI2IE = 0; //Disable The Interrupt
SPI2CON1bits.DISSCK = 0; //Internal Serial Clock is Enabled
SPI2CON1bits.DISSDO = 0; //SDOx pin is controlled by the module
SPI2CON1bits.MODE16 = 0; //Communication is byte-wide (8 bits)
SPI2CON1bits.SMP = 0; //Input Data is sampled at the middle of data Output time
SPI2CON1bits.CKE = 1; //Data is valid on the rising edge of the clock (Transmit occurs on transition from active to idle clock state)
SPI2CON1bits.CKP = 0; //Clock low in idle bus state
SPI2CON1bits.MSTEN = 0; //Master Mode disabled
SPI2CON1bits.SSEN = 1; //SS pin enabled (the SSx pin must be enabled in Slave mode when CKE = 1)
SPI2STATbits.SPIROV =0; //No Receive Overflow has Occurred
SPI2STATbits.SPIEN = 1; //Enable SPI Module
IFS2bits.SPI2IF = 0; //Clear the Interrupt Flag
IEC2bits.SPI2IE = 1; //Enable The Interrupt
Interrupt
//***************************************
//***************************************
//********** SPI2 RX INTERRUPT **********
//***************************************
//***************************************
void __attribute__((__interrupt__,__auto_psv__)) _SPI2Interrupt(void)
{
WORD data;
if (SPI2STATbits.SPIROV)
{
//----- OVERFLOW ERROR -----
//If a new data word has been shifted into SPIxSR and the previous SPIxBUF contents have not been read, the SPIROV bit (SPIxSTAT<6>) is set.
//Any received data in SPIxSR is not transferred, and further data reception is disabled until the SPIROV bit is cleared. The SPIROV bit is not
//cleared automatically by the module; it must be cleared by the user application.
data = SPI2BUF;
SPI2STATbits.SPIROV = 0;
IFS2bits.SPI2IF = 0; //Clear the Interrupt Flag
return;
}
//----- READ THE DATA -----
data = SPI2BUF;
//----- WRITE THE NEXT DATA BYTE -----
//This needs to happen befoer the next byte/word is received. This irq is triggered 1/2 bit time before the end of the last bit of this byte/word, so if the master is fast we must service to her before the start of the first bit of the next byte/word.
SPI2BUF = data + 1; //Send back what we received + 1
IFS2bits.SPI2IF = 0; //Clear the Interrupt Flag
}
//******************************************
//******************************************
//********** SPI2 ERROR INTERRUPT **********
//******************************************
//******************************************
//SPIx Error Interrupt Flag (SPIxEIF) is set when the SPIROV bit is set. This interrupt flag must be cleared in software. The actual SPIx Error Interrupt
//is generated only when the corresponding SPIxEIE bit is set in the IECn Control register.
/*
void __attribute__((__interrupt__,__auto_psv__)) _SPI2ErrInterrupt(void)
{
}
*/
USEFUL?
We benefit hugely from resources on the web so we decided we should try and give back some of our knowledge and resources to the community by opening up many of our company’s internal notes and libraries through mini sites like this. We hope you find the site helpful.
Please feel free to comment if you can add help to this page or point out issues and solutions you have found, but please note that we do not provide support on this site. If you need help with a problem please use one of the many online forums.