View previous topic :: View next topic |
Author |
Message |
buneri
Joined: 23 Aug 2007 Posts: 14
|
SPI Slave Receiving byte is shifting |
Posted: Fri Oct 05, 2007 12:18 am |
|
|
Hi All,
I am using two PIC 16f87A chip for SPI communication.
Using PCWH 4.020
The master work fine, but the slave receiving the data with byte shifting.
Actually i wanna transfer four bytes of data at a time and simultaneously to receive by the slave in the same order.
But the slave receiving the data, with shifting of bytes not in the same order but the order of byte is changing contnuously.
Plz tell me wat i m doing wrong? Here is the coding of spi slave which i have used for receiving the data in order:
setup_sp(SPI_SLAVE|SPI_SS_DISABLED|SPI_MODE_0_1|SPI_CLK_DIV_16);
while(1)
{
while(!spi_data_is_in());
spi[i]=spi_read(0);
i++;
if(i==4)
{
data[0] = make16(spi[1],spi[0]);
data[1] = make16(spi[3],spi[2]);
hold_regs[0]=data[0];
hold_regs[1]=data[1];
//After that transfer it to the modbus master since its also modbus slave
}
for master
setup_spi(SPI_MASTER | SPI_MODE_0_0 |SPI_MODE_0_1| SPI_CLK_DIV_16);
Thanks |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Oct 05, 2007 6:56 am |
|
|
Your slave:
Code: | setup_sp(SPI_SLAVE|SPI_SS_DISABLED|SPI_MODE_0_1|SPI_CLK_DIV_16); | The master is the only device generating a clock signal. Specifying SPI_CLK_DIV_xx for the slave messes up your slave configuration.
Master:
Code: | setup_spi(SPI_MASTER | SPI_MODE_0_0 |SPI_MODE_0_1| SPI_CLK_DIV_16); | 1) The master and slave must have the same SPI_MODE_xxx configuration.
2) The hardware supports only 1 mode at a time. You can not specify two different SPI_MODE_xxx configurations, this does not work.
The v4.020 compiler is an early test version of the V4.0xx compiler and not stable. Use v3.249 or v4.030+. |
|
|
buneri
Joined: 23 Aug 2007 Posts: 14
|
Thanks Ckielstra |
Posted: Sat Oct 06, 2007 12:30 am |
|
|
Thanks for your response.
I have change the Mode of slave as per your advise. i.e, both master and slave now have Mode 0-1 .Now
setup_spi(SPI_SLAVE|SPI_SS_DISABLED|SPI_MODE_1_0
But the problem still there! bytes are same as transmitting but not receiving in the specific order
can u tell me plz wats the role of CKE in selecting modes, whats the method of selecting of suitable Mode and clock speed for SPI.
Thank You |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Oct 06, 2007 4:18 pm |
|
|
Code: | setup_spi(SPI_SLAVE|SPI_SS_DISABLED|SPI_MODE_1_0 | Here you have mode 1_0, but in your text and other code samples you are using 0_1. Double check to make sure master and slave are identical.
It is not important which of the four SPI-modes you choose, there are no big technical advantages from one mode over the other. Just make sure both sender and receiver use the same mode. |
|
|
buneri
Joined: 23 Aug 2007 Posts: 14
|
Thanks for clearifying me about SPI Modes |
Posted: Sun Oct 07, 2007 11:49 pm |
|
|
Dear Sir,
One thing i want to clearifying that is,
I am using SPI slave for just reading then,
for(i=0; i<4; i++)
data[i]=spi_read();
FL=make32(data[2],data[3],data[0],data[1]);
Is the above coding is correct for SPI?
Thanks |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Oct 08, 2007 5:21 am |
|
|
Quote: | Is the above coding is correct for SPI? | Hard to tell. The master and slave need to be identical, please also post the Master code.
Do you have implemented a Chip Select signal to the slave? If not, then how are you going to correct the situation where master and slave are out of sync? For example at power up there might be a power glitch causing your slave to see an invalid clock signal and hence your received data is shifted one bit. |
|
|
buneri
Joined: 23 Aug 2007 Posts: 14
|
|
Posted: Tue Oct 09, 2007 12:06 am |
|
|
Dear Sir,
Master Code with Chip Selec disabled
setup_spi(SPI_MASTER | SPI_MODE_1_0 | SPI_CLK_DIV_4);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
modbus_init();
//////////////////////////// While Loop /////////////////////////
while(1)
{
if(input(CS)
{
for(i=1; i<5; i++)
spi_write(reg_arayip1[i]);
}
CS is the synchronized bit from SPI slave for starting communication
because i need it for other task from slave to finish first
It works fine now but very rarely distrub the other tasks of SPI master
Thanks |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Tue Oct 09, 2007 11:12 am |
|
|
buneri wrote: | Dear Sir,
Master Code with Chip Selec disabled
setup_spi(SPI_MASTER | SPI_MODE_1_0 | SPI_CLK_DIV_4);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
modbus_init();
//////////////////////////// While Loop /////////////////////////
while(1)
{
if(input(CS)
{
for(i=1; i<5; i++)
spi_write(reg_arayip1[i]);
}
CS is the synchronized bit from SPI slave for starting communication
because i need it for other task from slave to finish first
It works fine now but very rarely distrub the other tasks of SPI master
Thanks |
It is possible to send data from the master much faster than the slave device would have time to receive it. I suggest you place a small delay between spi_write in the master code. Then reduce the delay period down as much as you can without making it stop working. The slave device code will compile better sometimes if you use direct addressing instead of an index in an array. It can be a trade off of size for speed. In this case it will be both faster and smaller and might not require the delays in the master.
Code: |
while(1)
{
output_bit (pin that drives CS on master, 1)
spi[0]=spi_read(0);
spi[1]=spi_read(0);
spi[2]=spi_read(0);
spi[3]=spi_read(0);
data[0] = make16(spi[1],spi[0]);
data[1] = make16(spi[3],spi[2]);
disable interupts that will use hold_regs
hold_regs[0]=data[0];
hold_regs[1]=data[1];
enable interupts that will use hold_regs
output_bit (pin that drives CS on master, 0)
Delay between reading data from the master.
}
|
|
|
|
|