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 function on non-spi PIC

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







SPI function on non-spi PIC
PostPosted: Tue Jul 26, 2005 8:19 am     Reply with quote

Hi,

I wonder, can i use the built-in SPI function for PIC without hardware SPI? such as 16F628A.

I know we can use software i2c, and i think we may can use software spi as well.

thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 26, 2005 9:38 am     Reply with quote

There is no #use spi() statement to let you specify the pins.
The spi functions only work with the hardware spi module.
If you don't have hardware module you must do it in software.

Look at these CCS example files:
c:\Program Files\Picc\Drivers\ds1302.c
c:\program files\picc\drivers\25640.c
c:\program files\picc\drivers\isd4003.c
c:\program files\picc\drivers\can-mcp2510.c

There are many more.
Kit
Guest







PostPosted: Thu Jul 28, 2005 1:56 am     Reply with quote

The code from 9356spi.c

Code:

void init_ext_eeprom() {
   short int i;

   output_low(EEPROM_DI);
   output_low(EEPROM_CLK);
   output_low(EEPROM_SELECT);
   i=input(EEPROM_DO);

   setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16);

   output_high(EEPROM_SELECT);
   spi_write(0x9);
   spi_write(0x80);
   output_low(EEPROM_SELECT);
}

void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data) {

   output_high(EEPROM_SELECT);
   spi_write(0xa);
   spi_write(address);
   spi_write(data);
   output_low(EEPROM_SELECT);
   delay_ms(11);
}



There are several places i cann't understand.

1. why is setup_spi() placed after setting EEPROM_DI, EEPROM_CLK, EEPROM_SELECT to low? I mean, Why not place setup_spi() before these statement?

2. What is the function of short int i? it seems that "i" has been assigned the value of EEPROM_DO, but do nothing actually. If it is just to set the EEPROM_DO to become float, why don't just use output_float().

3. 0x9 is 8-bit or 4-bit? if this is 8-bit, that it is 0000 1001 (0x09) or 1001 000 (0x90). if this is 4-bit, i suppose this is 1001 only.

4. I am not sure what exactly does the init_ext_eeprom() do. especially

Code:

   spi_write(0x9);
   spi_write(0x80);


5.
inside write_ext_eeprom()
Code:
 spi_write(0xa);
   spi_write(address);
   spi_write(data);


i suppose spi_write(0xa) is the instruction for writing. However, from the datasheet downloaded from microchip.com, SB (start bit) + Opcode is only 3 bit. So i don;t know where the 0xa come from. again, 0xa is 4-bit (1010) or 8-bit (0000 1010)?

Thanks.
Guest








PostPosted: Thu Jul 28, 2005 3:26 am     Reply with quote

Code:


void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data) {

   output_high(EEPROM_SELECT);
   spi_write(0xa);
   spi_write(address);
   spi_write(data);
   output_low(EEPROM_SELECT);
   delay_ms(11);
}


BYTE read_ext_eeprom(EEPROM_ADDRESS address) {
   BYTE data;

   rotate_left(&address,1);
   output_high(EEPROM_SELECT);
   spi_write(0x18|(address&1));
   spi_write(address);
   data=spi_read(0);
   output_low(EEPROM_SELECT);

   return(data);
}


According the datasheet from microchip.com, a state in page 11:
Code:

CS must be low for 250 ns minimum (TCSL) between
consecutive instructions. If


6. I notice that, the delay_ms() in write_ext_eeprom is 11. Is this a random number, as long as this number is larger than 250ns?

7. why does read_ext_eeprom() and init_ext_eeprom() doesn't require the delay for atleast 250 ns?

Thanks
Ttelmah
Guest







PostPosted: Thu Jul 28, 2005 3:58 am     Reply with quote

Remember instructions take time. On the typical PIC, at 10MHz each instruction takes 250nSec. Even at 40MHz, the instructions take 100nSec each. By the time you have returned a data byte from the routine, the CS line has already been low for long enough.
On the write though, the problem is how long the chip takes to write a byte. Typical write times for this sort of EEPROM, are in the order of 6mSec. There are two choices open, either make the write 'poll' the chip for an ACK, and only then write to it, or wait more than the worst case write time, after a write. The code as posted, has used the second approach. It'd probably work fine with the time dropped to 6mSec, but check the data sheet for the write time, before trying this.

Best Wishes
Guest








PostPosted: Thu Jul 28, 2005 5:26 am     Reply with quote

Ttelmah, Thanks for ur xplanation. I thought each instruction takes 1/frequency, for 40 Mhz, each instruction takes 25ns. Smile

I also couldn't understand the statement below in read_ext_eeprom()

Quote:
spi_write(0x18|(address&1));

I don't know where the 0x18 comes from and where does the address have to AND with 1.
Ttelmah
Guest







PostPosted: Thu Jul 28, 2005 7:30 am     Reply with quote

Each instruction on a PIC, takes four clock cycles. 4/40000000=100nSec.
Your 'read' command differs from the one in 9356spi.c. The version I have has:
Code:

BYTE read_ext_eeprom(EEPROM_ADDRESS address) {
   BYTE data;

   output_high(EEPROM_SELECT);
   spi_write(0x18);
   spi_write(address);
   data=spi_read(0);
   output_low(EEPROM_SELECT);

   return(data);
}


I think your version is 'old', and has the incorrect values for this part (the '&1' bit, is normally used on I2C chips to signify a 'read' instruction - this looks to have been incorrectly copied to the SPI code...).

Best Wishes
Guest








PostPosted: Thu Jul 28, 2005 8:34 pm     Reply with quote

Thanks Ttelmah.

The latest code is more self-explained.

when I compared 9356.c against 9356spi.c, the init_ext_eeprom() in 9356.c has an additional output_low(EEPROM_DI) above output_low(EEPROM_SELECT).

Why do we need to put that? I thought all the bit has been shifted out in the for loop.

Code:
void init_ext_eeprom() {
   BYTE cmd[2];
   BYTE i;

   output_low(EEPROM_DI);
   output_low(EEPROM_CLK);
   output_low(EEPROM_SELECT);

   cmd[0]=0x80;
   cmd[1]=0x9;

   for(i=1;i<=4;++i)
      shift_left(cmd,2,0);
   output_high(EEPROM_SELECT);
   for(i=1;i<=12;++i) {
      output_bit(EEPROM_DI, shift_left(cmd,2,0));
      output_high(EEPROM_CLK);
      output_low(EEPROM_CLK);
   }
   output_low(EEPROM_DI);
   output_low(EEPROM_SELECT);
}


Thanks.
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