CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

SPI problem - PIC16f877a to MCP2515

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Chris b
Guest







SPI problem - PIC16f877a to MCP2515
PostPosted: Fri Jun 01, 2007 10:38 am     Reply with quote

Hi,
i'm having a problem when using an SPI interface to communicate between a PIC16f877a and an MCP2515 CAN controller, using the CCS pic C compiler.

The following code is supposed to test the SPI interface by writing to a register in the MCP 2515, then reading it back. the problem is that some of the bits read back are different from those sent. I've put in a function to clear the BF bit (as suggested in the PIC16f877a datasheet) before the read takes place, but it doesnt make any difference.



while (TRUE)
{

for (k=0; k<=0xFF; k++)
{
output_low(CAN_CS); //begin SPI comms
spi_write(WRITE); //send the write instruction
spi_write(0x34); //address of a register to test reading and writing
spi_write(k); //send the data
output_high(CAN_CS); //SPI comunication finished
restart_wdt(); // restart the watchdog timer
delay_ms(50); //wait for 50ms before the read occurs

output_low(CAN_CS); //start another round of SPI comms
spi_write(READ); //send the read instruction
spi_write(0x34); //read from the register the data was written to


clear_BF(); //clear bit BF before reading the input data
i = spi_read(0x00); //read the value of the register into i
output_high(CAN_CS); //SPI comunication finished


i = i ^ k ; //XOR together to make bits where an error has happened = '1'

output_d(i); //output the errors onto LEDs for visual inspection
restart_wdt(); // restart the watchdog timer
delay_ms(50); //wait for 50ms before going round the loop again

}

}



the SPI port on the pic is configured as follows:

setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_64 | SPI_XMIT_L_TO_H | SPI_SAMPLE_AT_END);

i've tried with various clock pre-scalers, sampling in the middle instead of the end, and opposite clock polarity, all to no avail.

i know the CAN controller is getting at least some SPI instructions, as i am able to change it's clock out pre-scaler via SPI successfully.

any suggestions?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jun 01, 2007 1:26 pm     Reply with quote

Try the test program shown in this thread.
http://www.ccsinfo.com/forum/viewtopic.php?t=18539

Note that he initially has a problem with the SPI interface
because he's using SPI Mode 2, and the MCP2515 data sheet
says that it must use mode 0 or 3. Later in the thread, he
changes his setup_spi() statement to use SPI mode 3.

It's easier to setup the correct SPI mode if you use these definitions.
Code:

#define SPI_MODE_0_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_0_1  (SPI_L_TO_H)
#define SPI_MODE_1_0  (SPI_H_TO_L)
#define SPI_MODE_1_1  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

Edit his code to use mode 0 or mode 3 and then try it.
Also change the #define statements for the \Reset and \CS
pins to match your hardware.
Chris B
Guest







PostPosted: Mon Jun 04, 2007 3:22 am     Reply with quote

will give it a try, thanks
chris b
Guest







PostPosted: Mon Jun 04, 2007 8:09 am     Reply with quote

think i've got it sorted now, the other threads with explanation of modes etc were very useful.. a l
but what seems to have solved my problem was to specifically set TRIS<C> such that SDI pin of the PIC is configured as an input - something which the data sheet claims you don't have to do.
Thanks again for the help - a veritable resource of info this forum

:-)
aswinthomas
Guest







mcp2515
PostPosted: Tue Jul 24, 2007 7:33 am     Reply with quote

hi
i am also suffering with the same problem
i also want to set mode0,0 or mode1,1 as
per the data sheet ,i am doing this in assembly
can u explain me that which bit must be set
for it,i will be thankfull for it


aswin
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Jul 24, 2007 7:58 am     Reply with quote

Code:

//     MOTOROLA    |      MICROCHIP      |           CCS
//-----------------------------------------------------------------------
//   SPI Mode 0,0  |   CKP = 0, CKE = 1  |  SPI_L_TO_H | SPI_XMIT_L_TO_H
//   SPI Mode 0,1  |   CKP = 0, CKE = 0  |  SPI_L_TO_H
//   SPI Mode 1,0  |   CKP = 1, CKE = 1  |  SPI_H_TO_L
//   SPI Mode 1,1  |   CKP = 1, CKE = 0  |  SPI_H_TO_L | SPI_XMIT_L_TO_H
ASWIN
Guest







MCP2515
PostPosted: Wed Jul 25, 2007 12:22 am     Reply with quote

HI CKIELSTRA,
THANKS for ur code ,i tried it in my code
but its not working i dont no wats the
mistake i here attched my code can u
tell me were the mistake or if possible
post me a code for spi_initialisation and
one for r/w for mcp2515 once again thanks



CS=0;
asm("nop");
SSPBUF=0B00000010;//write inst
SSPBUF=0X30;
SSPBUF=0b11100111;//data
CS=1;

delay(25000);


CS=0;
SSPBUF=0b00000011;//read inst
asm("nop");
SSPBUF=0X30;
asm("nop");
asm("nop");
HOLDER=SSPBUF;
CS=1;

asm("nop");
asm("nop");
asm("nop");
if(HOLDER==0b11100111)
{
PORTA=0X3F;
while(1)
{
}
}
while(1)
{
RA0=1;
}
}
//**************************************************************
void spi_interface (void)
{
TRISC =0b00010000; // setting SDO,SDI,SCK pins.SDI must set as input
//****************
//SSPSTAT
//****************
STAT_SMP=1; //Sample bit.Input data sampled at middle of data out put time
STAT_CKE=1; //SPI clock edge select. data trans on rising edge of SCK.case CKP=1.
//****************
//SSPCON
//****************
CKP=1; //Clock polarity select bit.Idle state of clock is a high level
SSPEN=1; //Synchronous serial port enable bit.
SSPM3=0; //SSPM3:SSPM0- Synchronous serial port mode select bit
SSPM2=0;
SSPM1=0; //SPI master mode, Fosc/4.
SSPM0=0;
}

aswin thomas
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Jul 25, 2007 1:38 am     Reply with quote

Quote:
i also want to set mode0,0 or mode1,1
I gave you the correct settings, then why do you set CKE=CKP=1 ? These are the settings for mode 1,0.

Code:
STAT_SMP=1; //Sample bit.Input data sampled at middle of data out put time
The text and the program code do not match.
Also change to SMP=0 for a correct setup.

Code:
SSPBUF=0B00000010;//write inst
SSPBUF=0X30;
SSPBUF=0b11100111;//data
After each write to the SPI transmit buffer you will have to give the processor some time to transmit the data, for example by waiting in a loop until the BF flag gets set.

Sorry, I can't give you a complete driver. I don't know the mcp2515 and this forum is for the CCS C compiler, your compiler is different. I don't know how to do it for your compiler, best is to go to their website.
aswin
Guest







mcp2515
PostPosted: Wed Jul 25, 2007 2:18 am     Reply with quote

hi,
sorry man its of some posting
mistake i post my older code
once again sorry and thank u
for ur reply by

aswin
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group