Tuesday, 5 January 2016

SPI Clock on PIC unstable


I'm trying to configure the MSSP module of a PIC18F25K22 into SPI master mode. I'm looking at the timing and the clock doesn't remain steady through the whole transmission. A picture shows it better than words. SPI Timing Diagram


After a bit is sent, the clock shortens, and not by the same amount each time. I've not worked with SPI before, but the diagrams I've found on Wikipedia and other resources don't ever show this. I also hooked up an Arduino and did not see this behavior. My code is:


    #pragma config FOSC = INTIO67   // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)

#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

void main(void)
{
OSCCON = 0b11100110;
spi_setup();
__delay_ms(10);
byte temp;
while (TRUE)
{

temp = spi_transfer(0x00);
temp = spi_transfer(0x01);
temp = spi_transfer(0x02);
temp = spi_transfer(0x03);
temp = spi_transfer(0x04);
temp = spi_transfer(0x05);
__delay_us(1);
}
}


void spi_setup(void)
{
SSP1STAT = 0b00000000;
SSP1STATbits.CKE = HIGH; // data transmitted on rising edge
SSP1CON1 = 0b00000000; // enable Master SPI mode
SSP1CON1bits.CKP1 = LOW; //clock idle state is low
//i2c bits, all don't matters for SPI, cleared just in case
SSP1CON3 = 0;
// baud rate generation
SSP1ADD = 0; //FCLOCK = 8Mhz /2 = 2Mhz

// configure pins for output/input as needed
SDI1 = INPUT;
SDO1 = OUTPUT;
SCK1 = OUTPUT;
SS1 = OUTPUT;
SSP1CON1bits.SSPEN1 = HIGH; // enable pins for serial mode
}

unsigned char spi_transfer(unsigned char data)
{

SS1_LAT = LOW; // select slave
PIR1bits.SSPIF = LOW;
SSP1BUF = data;
//while (!SSP1STATbits.BF); //wait for receive to complete
while( !PIR1bits.SSPIF );
SS1_LAT = HIGH; // deselect slave
PIR1bits.SSPIF = LOW; // clear interrupt
return SSP1BUF; //return data from the slave
}


(also https://gist.github.com/stumpylog/5095250 )


Has anyone encountered this or have suggestions as to the cause?


What I Did


In the end, I was unable to get the MSSP1 module working. However, changing it to the MSSP2 module, exact same code, did not exhibit this behavior. I can't explain it, but this solved the problem.




No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...