Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help on SPI programming (C) for PIC16F877 !!

Status
Not open for further replies.

reddster

Newbie level 3
Joined
Feb 16, 2006
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,345
spi protocol basics+pic16f877

Hi to all!

I am a student undergoing a project which involves the interfacing
of the PIC16F877 to a Phase locked loop device(ADF4360-8) using the SPI.

Basically, I need to send out, via SDO, 3 batches of 24 bits to
the device to initialise it. I am worried that i might miss a few lines
of code because i could not detect the SCK signal from the SCK pin (RC3).
Also, am I doing it correctly for the initialisation of the SSPSTAT, SSPCON
and the sending part?

I fully appreciate your help!!

This is my code in C Language:


#include <pic1687x.h>
#include "delay.c"


void main () {


PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;

TRISC = 0b00010000; //RC4=SPI Data In
TRISD = 0x00;
TRISB = 0b00000001; //RB0=input
TRISA = 0x00;
TRISE = 0x00;


//initialise PLL
//R counter = 0011 0000 0000 0000 0111 1001
//Control latch = 0000 1111 1111 0001 0000 0100
//N counter = 0000 0000 1011 0100 0000 0010



SSPSTAT = 0b01000000;
SSPCON = 0b00100010;

SSPBUF = 0b00110000; //R counter
SSPBUF = 0b00000000;
SSPBUF = 0b01111001;
RA5 = 1; //LE high to transfer data from shift register to latch
RA5 = 0;

SSPBUF = 0b00001111; //Control
SSPBUF = 0b11110001;
SSPBUF = 0b00000100;
RA5 = 1; //LE high to transfer data from shift register to latch
RA5 = 0;

DelayMs(20); //Delay between Control and N Counter

SSPBUF = 0b00000000; //N Counter
SSPBUF = 0b10110100;
SSPBUF = 0b00000010;
RA5 = 1; //LE high to transfer data from shift register to latch
RA5 = 0;


while(1){

if(RB0==1)//When RB0 is high, pull CE pin high to turn on PLL
RC1 = 1;
if(RB0==0)//When RB0 is low, pull CE pin low to turn off PLL
RC1 = 0;

}
} //end of main


Thanks again!!
 

philba

Full Member level 2
Joined
Jan 26, 2006
Messages
132
Helped
13
Reputation
26
Reaction score
1
Trophy points
1,298
Activity points
3,102
spi sample in pic16f877 in c

I've not used the 877s MMSP but I think you need to check to make sure SSPBUF has emptied before writing the next byte. The apnote says something about checking WCOL.
[edit] just found this decent tutorial on the microchip site https://ww1.microchip.com/downloads/en/devicedoc/spi.pdf It says you need to check the Buffer full flag and read the buffer even if only writing data. [/edit]

how fast is your PLL device? You've set the SPI clock at Fosc/64 At 20mhz clock, you are running it at 20/65 mhz. or 3.2 uS per bit. You might have to bit bang SPI if that's too fast. Bitbanged SPI is very very easy. Unless you need the speed of the MSSP device, I'd bit bang SPI anyway since a) its a very simple protocol and b) I prefer to save the MSSP for higer performance uses (like serial I/O or I2C).

Phil
 

    reddster

    Points: 2
    Helpful Answer Positive Rating

reddster

Newbie level 3
Joined
Feb 16, 2006
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,345
spi programming

Oh..thanks a lot for your reply and the link..So, basically, I need to do a dummy read to clear the SSPBUFF before I can do the next transmit? Also, regarding the need to check the buffer status before trnsmitting the next byte, I am confused about which bit i need to check. Is it WCOL or SSPOV.

---------------------------------------------------------------------------------------
Here is an excerpt from the PIC16F877 datasheet regarding the 2 bits:

WCOL: (Master Mode) 1 = A write to SSPBUF was attempted while the I2C conditions were not invalid
0 = No collision

SSPOV: (SPI Mode) 1 = A new byte is received while the SSPUF holds previous data. Data in SSPSR is lost on overflow. In Slave mode, the user must read the SSPBUF, even if only transmitting data, to avoid overflows. In Master mode, the overflow bit is not set, since each operation is initiated by writing to the SSPBUF register. (Must be cleared in software).
0 = No overflow
---------------------------------------------------------------------------------------

From the link given by Phil, I understand the need to do a dummy read after each transmit. But how do I know when the transmit is done before I can actually perform the dummy read?

Thank you for your kind help!
 

philba

Full Member level 2
Joined
Jan 26, 2006
Messages
132
Helped
13
Reputation
26
Reaction score
1
Trophy points
1,298
Activity points
3,102
+spi programming

no, you have to loop waiting for the buffer full flag, then do the read.
 

reddster

Newbie level 3
Joined
Feb 16, 2006
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,345
spi get char send dummy sspbuf

Thanks for the info!:D So, am I doing it right in the following code?


#include <pic1687x.h>
#include "delay.c"

char dummy_read_byte;

void spi_send(char);

void main () {


PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;

TRISC = 0b00010000; //RC4=SPI Data In
TRISD = 0x00;
TRISB = 0b00000001; //RB0=input
TRISA = 0x00;
TRISE = 0x00;


SSPSTAT = 0b01000000;
SSPCON = 0b00100010;

dummy_read_byte = SSPBUF; //do a dummy read

spi_send(0b00110000);
spi_send(0b00111110);
spi_send(0b10100011);

}
} //end of main



void spi_send(char data) {

int i=0;
char dummy_read;
char bf_status;

SSPBUF = data; //send byte


while(i != 1) { //do not exit loop unless BF bit = 0
bf_status = SSPSTAT & 0x01; //check if BF bit is 0
if (bf_status == 0x00)
i = 1;
}

dummy_read = SSPBUF; //dummy read

}


Thanx in advance! :D
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top