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 with 16F88

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







SPI Problem with 16F88
PostPosted: Mon Jul 21, 2008 9:03 am     Reply with quote

Hello
I am having a problem with SPI interface to communicate between a PIC16F88 and a GPRS modem, using the CCS pic C compiler.

The problem is that sometimes the value is wrong an the rest of time the byte is one bit shift.

Code:


setup_spi(SPI_SLAVE|SPI_L_TO_H|SPI_CLK_DIV_16);



EXT_isr() {
   if (input(SS)==0)   //se ha activado el SS
   {
      while (!spi_data_is_in());      
      data_spi[aux] = spi_read();
      aux++;
   }
}


I have tried with different configurations, but all time the read value is incorrect.

thank you
Ttelmah
Guest







PostPosted: Mon Jul 21, 2008 10:41 am     Reply with quote

First, a slave _does not have a clock setting_. The most likely problem is that setting this, is resulting in incorrect configuration of the registers.
Now, your 'code', makes it impossible to have a hope of knowing what is really going on. What is int_ext connected to?. What SPI 'mode' does the modem use?. What speed?. etc. etc..

Best Wishes
Guest








PostPosted: Tue Jul 22, 2008 1:05 am     Reply with quote

Hi,

The mode configuration that I use is: 2MHz, the data valid on rising edge.

I have connect the SS to input of port B, and I have configured the INT_RB:

ext_int_edge( H_TO_L );
enable_interrupts(INT_RB);

When the SS change the interruption jump, and call the next funtion:

Code:

#INT_RB

EXT_isr() {
    if (input(SS)==0)               
   {   
         flag_spi=1;     
         while (!spi_data_is_in());         
         data_spi[aux] = spi_read();
    }
}


I have tried without clock setting, but the problem is the same, sometimes the value is incorrect and other times it read anything.

I saw the problems the other people and I changed the configuration for this:

Code:

setup_spi(SPI_SLAVE | SPI_SS_DISABLED | SPI_L_TO_H | SPI_XMIT_L_TO_H);


In this case the read value is correct all times, but some time the interruption ocurrs but it ready any data.


Thank you[/code]
Ttelmah
Guest







PostPosted: Tue Jul 22, 2008 3:01 am     Reply with quote

That is not the SPI mode.
There are four standard SPI modes. The GPRS modem, will say somewhere in it's data sheet a comment like 'compatible with SPI mode 0'. This defines both how data is sent by it, and how the receiving device has to send it's data. It is about 3000% easier to setup SPI, by just identifying the mode number, and then looking up the required PC settings (a table of modes to CCS codes, has been published here many times...).
It sounds as if your device uses mode 0, since the combination you have working, is the setting for this.
Key problem was that you are not actually 'using' SS. SS, is a hardware pin with the SPI, and requires you to use this pin. However it raised the comment, 'why not'. If you connected the SS pin to the hardware pin, and instead of using INT_EXT (which as it stands, you are stuck in for the receiving of the whole command string), just use the INT_SSP. You will receive an interrupt for each byte, and can simply set a flag when the last byte is seen to tell your main code that the data is ready.
As it stands, the code will not work properly, since in most devices, 'SS' will not go high, for a short period _after_ the last byte has been sent. Your code sees the last byte, transfers it into the buffer, then tests the input pin, which is still low, so goes back to waiting for another byte, which does not arrive, till the next frame begins. Hence you will have to wait for the next command to start, and will receive the bytes 'out of sync'.
Use the hardware, and count the received bytes, so you know when the packet has finished.

Best Wishes
prog
Guest







PostPosted: Tue Jul 22, 2008 4:09 am     Reply with quote

I have seen the datasheet and the GPRS modem uses mode 0.

I have tried to change the INT_RB by INT_SSP and use SS, but the problem persists.
ckielstra



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

View user's profile Send private message

PostPosted: Tue Jul 22, 2008 3:58 pm     Reply with quote

Quote:
I have connect the SS to input of port B, and I have configured the INT_RB:

ext_int_edge( H_TO_L );
enable_interrupts(INT_RB);
It looks like you have mixed up INT_RB and INT_EXT.
INT_EXT: activated by a change on the INT pin (B0, pin 6). The edge generating the interrupt is selected by calling ext_int_edge().
INT_RB: this interrupt is triggered by any change on the pins B4 to B7. It is different from all the other interrupts in that the interrupt flag can not be cleared directly but only by reading from port B. For all interrupts the compiler clears the interrupt flag for you, but in INT_RB you have to ensure PORT_B is read.

With the above information I suggest you adapt your program.

Instead of code fragments please post a small test program. Make sure the program is complete, including all fuses, etc, so we can copy/paste it into our compiler. Keep it small as possible, maximum 20 lines.
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