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 support@ccsinfo.com

Hardware SPI not working in PIC18F4550

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



Joined: 25 Mar 2009
Posts: 5

View user's profile Send private message Yahoo Messenger

Hardware SPI not working in PIC18F4550
PostPosted: Wed May 27, 2009 1:14 pm     Reply with quote

I am trying to interface the Nokia 6610 color LCD with a pic18F4550. I can do everything with the LCD by using software spi i.e. bit banging but when I try to do the same using hardware SPI nothing happens at all. Here is the code that i am talking about

Code:

void nokia_write_dorc(char bytefornokia)         // serial write data or command subroutine
{
     char caa;
     for (caa=8;caa>0;caa--) {
       output_low(SCK);
       //delay_us(2);
       if ((bytefornokia&0x80)==0){output_low(SDO);}
       else {output_high(SDO);}
       output_high(SCK);
       bytefornokia=bytefornokia<<1;
     }

}


The above code snippet uses software SPI(bit banging SPI) but when I tries to use the following the LCD is not working

Code:

void nokia_write_dorc(char bytefornokia)         // serial write data or command subroutine
{
      setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
     output_low (SDO);
     //output_high (SCK);
     //delay_cycles(2);
     SSPEN = 1;
     spi_write(bytefornokia);
     //setup_spi(FALSE);
     SSPEN = 0;

}


I have tried all the clock frequencies in place of "SPI_CLK_DIV_16". I have even tried using timer2 at the same place but it was all in vain. I even tried using the #use SPI but still nothing happened. I tried to compile the code in two different version of CCS compilers (3.249 and 4.038) but still could not make it work. Can anybody please tell me what am i doing wrong that is preventing me from using the hardware SPI In place of the software(bit banging) SPI mode. I have set

#bit SSPEN = 0xFC6.5

The waveforms looks perfectly nice in Proteus simulation also the SPI debugger shows that the correct SPI data is being sent but when I implement it in the actual hardware it is not working. Please help.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 27, 2009 2:57 pm     Reply with quote

Quote:
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
Your software SPI code appears to be using SPI mode 0.
The SCLK idles low and the positive clock edge occurs in the center of
the data cell.
http://www.totalphase.com/support/kb/10045/#modes
http://elm-chan.org/docs/spi_e.html
Your setup_spi() statement is using the wrong mode. It's using mode 1.
Put the following #define statements above main(), and put SPI_MODE_0
in place of the middle parameter in your setup_spi() statement.
Code:
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)



Also, the SDO pin on the 18F4550 is multiplexed with the UART's Rx pin.
Do you have a #use rs232 statement that specifies the hardware UART
pins ? That could be the problem. You can't use the hardware UART
if you are using hardware SPI.
Ttelmah
Guest







PostPosted: Wed May 27, 2009 3:05 pm     Reply with quote

Start with telling us the clock rate of the chip.
Then, don't reprogram the SPI in the routine. Set it once at the start of your code, then don't fiddle again. Changing settings, (and manually overriding the SDO), could result in unwanted edges being generated.
You want CKE=1, and CKP=0, to generate the rising clock edge, after the data bit is sent, duplicating what your software does. This needs the SPI_XMIT_L_TO_H value added to your SPI setup.
This is probably the main problem.

Best Wishes
jitun



Joined: 25 Mar 2009
Posts: 5

View user's profile Send private message Yahoo Messenger

PostPosted: Wed May 27, 2009 10:46 pm     Reply with quote

@PCM programmer

I have tried using "SPI_XMIT_L_TO_H" but it still didn't work. However I still tried it again now and it didn't work. I am not using the UART.

@Ttelmah

I am using a 20MHz crystal with the HS fuse set. The following is the fuse and clock configuration
Code:
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,CPUDIV1,VREGEN
#use delay(clock=20000000)


Since the Nokia color LCD uses 9 bit spi I have to manually override the SDO pin to generate the 9th bit. Have a look at the code

Code:
void nokia_write_dorc(char bytefornokia)         // serial write data or command subroutine
{
     /*char caa;            //Software SPI working fine
     for (caa=8;caa>0;caa--) {
       output_low(SCK);
       //delay_us(2);
       if ((bytefornokia&0x80)==0){output_low(SDO);}
       else {output_high(SDO);}
       output_high(SCK);
       bytefornokia=bytefornokia<<1;
     }*/

     output_low (SDO);            //Hardware SPI never works
     output_low (SCK);
     SSPEN = 1;
     spi_write(bytefornokia);
     //while(!spi_data_is_in())
     SSPEN = 0;

}
void gclcd_cmd(int8 cmd)
{
   SSPEN = 0;            // turn off hardware SPI allowing us direct access to SPI in/out pins
   output_low (SCK);
   delay_cycles(1);
   output_low(CS);       // enable chip
   output_low (SDO);     // output low on data out (9th bit low = command)
   output_high (SCK);
   nokia_write_dorc(cmd);
   delay_cycles(1);
   output_high(CS);      // disable
}
// It sends data to the gclcd
void gclcd_data(int8 data)
{

   SSPEN = 0;            // turn off hardware SPI allowing us direct access to SPI in/out pins
   output_low (SCK);
   delay_cycles(1);
   output_low(CS);       // enable chip
   output_high (SDO);    // output high on data out (9th bit high = data)
   output_high (SCK);
   nokia_write_dorc(data);
   delay_cycles(1);
   output_high(CS);     // disable
}


As I said earlier using SPI_XMIT_L_TO_H also didn't work.

Please do reply.
Ttelmah
Guest







PostPosted: Thu May 28, 2009 2:22 am     Reply with quote

My comment about stop fiddling with the SPI pins, still applies. You risk generating extra clock edges, and if you do, it won't work.

Now, 20MHz, implies that the SPI will generate clocks at 5MHz, 1.25MHz, or 312500Hz from the standard clock. Your 'soft' code, will probably take about 20 instructions to test each single bit, three for each bit set/reset (three in each loop), and perhaps another ten for the arithmetic and loop. Probably something in the order of 40+ instructions for the loop. Probably even slightly more than this. Less than 1/3rd the rate of your slowest SPI setting. Now you say you have tried using timer2, but not what rate you programmed. So, try:

setup_timer_2(T2_DIV_BY_2,25,1);

This will give a SPI clock of 50KHz (timer2/2), which will be in the same order of speed as the software solution.

Have one SPI setup, just selecting SPI_MODE_0, from PCM's defines (much the safest way of setting up the SPI, to get the settings right), so:

setup_spi(SPI_MASTER|SPI_MODE_0|SPI_CLK_T2);

And get rid completely of changing the SDI/SDI pins. The _hardware_ sets the clock low as soon as the SPI port is setup. You don't need to touch the lines again.

Best Wishes
jitun



Joined: 25 Mar 2009
Posts: 5

View user's profile Send private message Yahoo Messenger

PostPosted: Thu May 28, 2009 11:29 am     Reply with quote

it worked with this setting
Code:

setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4);


But it needs a delay of minimum 25us after each SPI_write()? Why? and how can i make it work without the delay?
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