|
|
View previous topic :: View next topic |
Author |
Message |
Avarachan Guest
|
SPI problem btw 18f458 and 18f2221 |
Posted: Thu Mar 20, 2008 3:12 pm |
|
|
Hi,
I am using s/w spi on 18f458(master) and hw spi on 18f2221(Slave). Compiler is V4.032.
problem: I am trying to communicate to and fro bw the pics. I send two bytes from master to slave. I can read it and print it at slave. The waveforms look good too. following this, the slave sends two bytes to master.
1. The waveform on SDO is totally wrong. ie, wrong data.
>> I send 0xCB and 0xAA from master, and 0xEA and 0x2B from slave. But SDO on slave gives out 0xAA and 0x00.
2. slave SSPBUF shows 0xAA right after I write 0xEA. The waveform on SDO corresponds to AA.
master code:
#include <18f458.h>
#device *=16 adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT
#use delay(clock=16000000)
#use spi(MASTER, DI=PIN_C2, DO=PIN_C1, CLK=PIN_C0, BITS=8, MODE=0, MSB_FIRST)
void main ()
{
set_tris_c(0b10011100)
while(1)
{
j=spi_xfer(0xCB);
i=spi_xfer(0xAA);
delay_ms(1000);
}
}
slave code:
#include <18f2221.h>
#device *=16 adc=10
#fuses INTRC,WDT1024,NOLVP,NOPROTECT,NOXINST
#use delay(clock=8000000)
void main()
{
int a = 0, b=0;
int i,j;
setup_spi(SPI_SLAVE | SPI_L_TO_H);
while(1)
{
a = spi_read(0);
b = spi_read(0);
spi_write(0xea);
spi_write(0x2b);
printf(" %x %x", a,b);
}
}
Any hints/ help greatly appreciated.
Thx
Avarachan |
|
|
Ttelmah Guest
|
|
Posted: Thu Mar 20, 2008 4:12 pm |
|
|
With SPI, both transfers take place _at the same time_.
When the master clocks a byte to the slave, it _at the same time_, clocks back, whatever is in the slaves SPI buffer register. All the transactions are initiated, and controlled by the master. So, to send a byte 'back', the slave must write it into the buffer _before_ the master begins it's transfer. So:
Code: |
#include <18f2221.h>
#device *=16 adc=10
#fuses INTRC,WDT1024,NOLVP,NOPROTECT,NOXINST
#use delay(clock=8000000)
void main(void) {
int a = 0, b=0;
int i,j;
setup_spi(SPI_SLAVE | SPI_L_TO_H);
while(1) {
while (!spi_data_is_in()) {
//Do anything else you want here, while waiting for the master
}
a = spi_read();
while (!spi_data_is_in()) {
//Do anything else you want here, while waiting for the master
}
b = spi_read(0xea);
//You must load the return byte _before_ the next
//master transfer
while (!spi_data_is_in()) {
//Do anything else you want here, while waiting for the master
//When it reads your returned byte, you _will_receive another
//byte, so 'data_is_in' will again go true.
}
spi_read(0x2b); //You should read the byte
//and immediately put the next byte in the buffer
while (!spi_data_is_in()) {
//Do anything else you want here, while waiting for the master
//When it reads your returne byte, you _will_receive another
//byte, so 'data_is_in' will again go true. This will show it has
//transferred the byte.
}
//You should read again here, to clear the dummy 'forward' byte
//sent by the master, when it read your bytes, and clear the flag
//otherwise the ends will ge out of sync.
spi_read();
printf(" %x %x", a,b);
}
}
|
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 20, 2008 4:15 pm |
|
|
In the slave pic, the \SS pin is enabled by default. If you want to disable
it, you have to specifically "OR" in the SPI_SS_DISABLED constant.
Your Master PIC is not controlling a Slave Select pin, so you should
either add that feature to the master, or disable it in the slave. |
|
|
Guest
|
|
Posted: Fri Mar 21, 2008 2:23 pm |
|
|
Quote: | master code:
#include <18f458.h>
#device *=16 adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT
#use delay(clock=16000000)
#use spi(MASTER, DI=PIN_C2, DO=PIN_C1, CLK=PIN_C0, BITS=8, MODE=0, MSB_FIRST)
void main ()
{
set_tris_c(0b10011100)
while(1)
{
j=spi_xfer(0xCB);
i=spi_xfer(0xAA);
delay_ms(1000);
}
}
slave code:
#include <18f2221.h>
#device *=16 adc=10
#fuses INTRC,WDT1024,NOLVP,NOPROTECT,NOXINST
#use delay(clock=8000000)
void main()
{
int a = 0, b=0;
int i,j;
setup_spi(SPI_SLAVE | SPI_L_TO_H);
while(1)
{
a = spi_read(0);
b = spi_read(0);
spi_write(0xea);
spi_write(0x2b);
printf(" %x %x", a,b);
}
}
|
Thanks, Ttelmah and PCM prgrammer for responding.
To Ttelmah:
In my attempt to cut the code as short as possible for you guys, I missed out few lines. so my original code is
master code:
Code: | #include <18f458.h>
#device *=16 adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT
#use delay(clock=16000000)
#use spi(MASTER, DI=PIN_C2, DO=PIN_C1, CLK=PIN_C0, BITS=8, MODE=0, MSB_FIRST)
void main ()
{
set_tris_c(0b10011100)
while(1)
{
output_low(PDO7);// slave select
j=spi_xfer(0xCB);
i=spi_xfer(0xAA);
a=spi_xfer(0x00); // expects first byte from slave
b=spi_xfer(0x00); // expects second byte from slave
output_high(PDO7);
delay_ms(1000);
}
} |
slave code:
Code: |
#include <18f2221.h>
#device *=16 adc=10
#fuses INTRC,WDT1024,NOLVP,NOPROTECT,NOXINST
#use delay(clock=8000000)
void main()
{
int a = 0, b=0;
int i,j;
setup_spi(SPI_SLAVE | SPI_L_TO_H);
while(1)
{
a = spi_read(0);
b = spi_read(0);
spi_write(0xea);
spi_write(0x2b);
printf(" %x %x", a,b);
}
} |
To PCM programmer:
I did have the /SS line controlled by the master, though I accidentally forgot to post it. So getting back to square one, I can get half part working. ie slave prints CB and AA. But everything else from there goes wrong as stated in my previous post
Quote: |
I am trying to communicate to and fro bw the pics. I send two bytes from master to slave. I can read it and print it at slave. The waveforms look good too. following this, the slave sends two bytes to master.
1. The waveform on SDO is totally wrong. ie, wrong data.
>> I send 0xCB and 0xAA from master, and 0xEA and 0x2B from slave. But SDO on slave gives out 0xAA and 0x00.
2. slave SSPBUF shows 0xAA right after I write 0xEA. The waveform on SDO corresponds to AA.
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 21, 2008 3:18 pm |
|
|
My advice is to look at the CCS example files for an SPI slave:
Quote: |
c:\Program Files\picc\Examples\Ex_spi_slave.c
c:\Program Files\picc\Examples\Ex_spi.c
|
Also, this thread has code that demonstrates an SPI slave
but it's done using one board (because it's a demonstration).
http://www.ccsinfo.com/forum/viewtopic.php?t=26888 |
|
|
|
|
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
|