View previous topic :: View next topic |
Author |
Message |
Chicky
Joined: 04 Aug 2005 Posts: 21
|
PIC to PIC spi interface problem... |
Posted: Wed Mar 29, 2006 1:24 am |
|
|
Hi...
I'm trying to interface 2 pic16f877a using spi...
1 as master that will send data
1 as slave that will read the data and send it to rs232 port.
the thing is the data i'm sending is from a array buffer that consist of
9 int8...
here is snippet of my master code:
Code: |
int8 buff8[8]={1,2,3,4,5,6,7,8};
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_64 | SPI_XMIT_L_TO_H);
output_bit(pin_e0,1); //SPIdata marker
for(i=0;i<=8;i++)
{
spi_write(buff8[i]);
delay_ms(100);
}
output_bit(pin_e0,0); |
and here is snippet of my slave code:
Code: | setup_spi(SPI_SLAVE | SPI_L_TO_H | SPI_SS_DISABLED);
for ( ; !input(PIN_D3); ) //Detected a low to high transition PIN_D3
;
for (i=0;i<=8;i++)
{
//if(spi_data_is_in())
buff8[i]=spi_read();
}
for(i=0; i<=8; i++)
printf("\r\n%x",buff8[i]); |
what i get is some numbers that have no connection with the contents of buff8[i]... this is really puzzling me..
could someone help??
btw.. is it matters that i use 20M crystal for master and 4M at slave?
Thanks sooo much for ur help@suggestion! |
|
|
Ttelmah Guest
|
|
Posted: Wed Mar 29, 2006 2:43 am |
|
|
As a general 'comment', I'd say that a while loop is 'tidier' than a for, to wait for the input pin to change. However this is purely 'aesthetic'.
Speed is not your problem. The SPI bus is being clocked incredibly slowly (master clock/64, and then allowing 100mSec between bytes!). A few uSec betwen bytes to allow time for the array access in the slave is more than adequate.
The problem is your SPI setup. The 'SPI_L_TO_H' definition, tells the units which 'edge' to read the data on. The 'SPI_XMIT_L_TO_H' defintion, tells the master which edge to _change_ the data on. You are telling the slave, to read the data on the same clock edge that it _changes_...
Best Wsihes |
|
|
Chicky
Joined: 04 Aug 2005 Posts: 21
|
|
Posted: Wed Mar 29, 2006 6:46 pm |
|
|
thanks Ttelmah...
i've removed the 'SPI_XMIT_L_TO_H' def, but not manage to get the desired result..
here is example of what i get
Quote: | 05
08
01
05
03
05
06
01
02
06
03
05
06
01
02
07 |
i've also change the 'for' to 'while' for the input change...
any other ideas? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 29, 2006 7:02 pm |
|
|
Quote: |
int8 buff8[8]={1,2,3,4,5,6,7,8};
for (i=0;i<=8;i++)
{
//if(spi_data_is_in())
buff8[i]=spi_read();
}
|
One problem with your code is that you're using "less than or equal to 8"
as the test in all your for(;;) loops. Those loops are going to process
9 elements, not 8. You are then writing past the end of the array and
you will corrupt some other variable. This can cause flaky operation
of the program or it could crash.
To process only elements 0 through 7, you need to do the loop like this,
with a "less than" test:
Code: |
for(i=0; i<8; i++)
{
buff8[i]=spi_read();
} |
|
|
|
Guest
|
|
Posted: Thu Mar 30, 2006 1:48 am |
|
|
PCM.. i already tried that.. still got the same result...
hmmm.. this is quite frustrating |
|
|
Chicky
Joined: 04 Aug 2005 Posts: 21
|
|
Posted: Thu Mar 30, 2006 2:17 am |
|
|
Yay~~ at last!!
u guys wanna know what i did?
i added this part:
Code: |
for (i=0;i<8;i++)
{
while (SSPBUF==0)
;
data=spi_read();
printf("\r\n\ndata: %d",data);
SSPBUF = 0;
}
printf("\r\n");
|
clearing SSPBUF really helped!!
now what i get are:
Quote: | data: 1
data: 2
data: 3
data: 4
data: 5
data: 6
data: 7
data: 8 |
thanks for ur help~~ |
|
|
|