|
|
View previous topic :: View next topic |
Author |
Message |
Kit Guest
|
SPI function on non-spi PIC |
Posted: Tue Jul 26, 2005 8:19 am |
|
|
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
|
|
Posted: Tue Jul 26, 2005 9:38 am |
|
|
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
|
|
Posted: Thu Jul 28, 2005 1:56 am |
|
|
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
|
|
Posted: Thu Jul 28, 2005 3:26 am |
|
|
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
|
|
Posted: Thu Jul 28, 2005 3:58 am |
|
|
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
|
|
Posted: Thu Jul 28, 2005 5:26 am |
|
|
Ttelmah, Thanks for ur xplanation. I thought each instruction takes 1/frequency, for 40 Mhz, each instruction takes 25ns.
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
|
|
Posted: Thu Jul 28, 2005 7:30 am |
|
|
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
|
|
Posted: Thu Jul 28, 2005 8:34 pm |
|
|
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. |
|
|
|
|
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
|