|
|
View previous topic :: View next topic |
Author |
Message |
franck Guest
|
spi with 2 Pic |
Posted: Tue Jan 04, 2005 2:16 am |
|
|
I try to make an interface spi with 2 Pic but that does not function. Is what somebody can help me please?
Here my code.
// SDO bit 5 patte 24 RC5
// CLK bit 3 patte 18 RC3
// SDI bit 4 patte 23 RC4
//*********************** includes and uses....***********************************/
#include <sk18f4x2.h>
#include <sk4x2_driver_lcd.c>
#include <sw_anti_rebond.c>
#use delay (clock=10000000) // 10MHz pour l'emulation et 10 MHz pour la programmation
// fuses pour programmation définitive
#fuses HS, NOPROTECT, NOOSCSEN, BROWNOUT, NOWDT, BORV27, PUT, CCP2C1, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
//************************************************************************************************************************************************
//
//
//Initialisation
//
//************************************************************************************************************************
u_switch sw_ok, sw_menu_esc, sw_plus, sw_minus;
byte string1[] = "Bonjour";
// comme on doit manipuler les bits, il faut également pouvoir y accéder par un word
// enfin, le format est en entier signé, if faut donc également pouvoir y accéder par un signed int
typedef union {
struct
{
byte lsb;
byte msb;
byte Cmd;
} Comd_Addr;
int8 Protocole;
} t_module;
t_module module; //byte a envoyer au slave
//******************************************Routine Timer 0 *****************************************************************************
// *****************************
// fonction de gestion de l'interruption du timer 0
//*******************************
#INT_TIMER0
interruption_timer0()
{
set_timer0(0xfe70); // pour 10ms : 10ms/
sw_ok.bits.valeur_lue = input(PIN_B3);
sw_anti_rebond (&sw_ok);
sw_menu_esc.bits.valeur_lue = input(PIN_B0);
sw_anti_rebond (&sw_menu_esc);
sw_plus.bits.valeur_lue = input(PIN_B1);
sw_anti_rebond (&sw_plus);
sw_minus.bits.valeur_lue = input(PIN_B2);
sw_anti_rebond (&sw_minus);
}
/*************************************************************************************************************/
/********************************************************************************************************/
void Master()
{
setup_spi(spi_master |spi_h_to_l |spi_clk_div_64 );
//while( !spi_data_is_in() )
{
SPI_WRITE (0x01);
SPI_WRITE (0x02);
SPI_WRITE (0x03);
module.comd_addr.lsb=spi_read();
module.comd_addr.cmd=spi_read();
module.comd_addr.msb=spi_read();
}
}
/*********************************************************************************************/
void slave()
{
setup_spi(SPI_SLAVE|SPI_SS_DISABLED|spi_l_to_h |spi_clk_div_64 );
while( !spi_data_is_in() )
{
module.comd_addr.lsb=spi_read();
module.comd_addr.cmd=spi_read();
module.comd_addr.msb=spi_read();
output_high(PIN_E2);
}
}
/**********************************************************************************************/
void main()
{
setup_timer_0 (RTCC_INTERNAL | RTCC_DIV_1);
// pour 10ms : 0-(10ms/100ns/4) = 0-400 = 0-0x190 = 0xfe70
set_timer0(0xfe70); // pour 10ms
enable_interrupts(INT_TIMER0);
enable_interrupts(global);
sw_init_struct(&sw_ok);
sw_init_struct(&sw_menu_esc);
sw_init_struct(&sw_plus);
sw_init_struct(&sw_minus);
while(1)
{
if (sw_menu_esc.bits.juste_presse == true)
{
if (sw_menu_esc.bits.toggle == true)
{
Master();
}
}
if (sw_plus.bits.juste_presse == true)
{
if (sw_plus.bits.toggle == true)
{
slave();
// output_high(PIN_E2);
}
}
}
} |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Jan 04, 2005 3:21 am |
|
|
The most obvious mistake: Quote: | setup_spi(SPI_SLAVE|SPI_SS_DISABLED|spi_l_to_h |spi_clk_div_64 );
| For a slave you should never specify the clock speed! In your code example this causes the compiler to generate an invalid SPI configuration.
change to Code: | setup_spi(SPI_SLAVE|SPI_SS_DISABLED|SPI_L_TO_H); |
Another possible problem is that master and slave are configured to clock the data out on different clock edges (spi_l_to_h and spi_h_to_l). |
|
|
Ttelmah Guest
|
|
Posted: Tue Jan 04, 2005 4:28 am |
|
|
Also remember that the SDO line of each chip must connect to the SDI line of the other, while the SCLK line goes straight across.
As written, I can't quite see how it is going to work. You have to remember that SPI, is a bi-directional interface. You write three bytes with the master, then try to read three bytes. Each 'write', transfers a byte _in both directions_. When you write a byte to the slave, the byte already sitting in the slaves SPI data register, will be clocked 'back' at the same time. Hence when you send '1', you will get back any data 'left' sitting in the register. Then when you send '2', you will get back the '1' that was sent last time (since the slave has not written any return data). This will happen to the third byte. spi_read, without a value, wil retrieve the value in the register, if one is waiting, and just sit, if one is not.
Then you try to 'read'. The register at this point will contain '2', and this will be returned for the first read. The master will then sit trying to read, and get nowhere (it after all, controls the bus, and you are asking it to read more data that does not yet exist...).
The sequence should be:
Code: |
MASTER SLAVE
spi_write spi_read - gets the first byte
spi_write spi_read
spi_write spi_read
At this point, the master _must_ wait long enough for the slave to transfer the byte to return to it's output register. Remember the slave does not 'receive' the data till the end of the write command, and the returned data _must_ be waiting in the register for the next set of clocks.
spi_write(byte to return)
spi_read(0)
Adding the '0' here, forces the master to generate the clocks to retrieve the data from the slave. You could instead use:
spi_write(val)
spi_read()
Which then allows another value to be sent to the slave at the same time as the master is retrieving the one waiting.
This 'write by slave', and retrieval by master, is then repeated for each byte required. Again there must be enough time between retrieving each byte at the master, for the slave to load the return data.
|
The 'simultaneous' nature of the transfer in both directions, combined with the output buffer being only one byte deep, means that the timing at the master end, must be carefully selected to allow the data to be prepared.
Note also, that the slave, does not really have to sit polling the spi_data_is_in flag, since if you issue the spi_read, it will sit and wait for the incoming byte to arrive. The flag is of course vital, if the slave has to do other things while waiting, but if so, you must ensure there is enough time between the successive bytes for the slave to always 'catch' one that has arrived (this may require a pause between bytes at the master).
One way to minimise this, is to have the slave write a '0' to the output bffer, when it goes off to do other things, then when it 'sees' a byte arrive, put a 'FF' in the register. The master can then send the first byte, then sit using spi_read(0), and when it sees a '0', it knows that the slave is now waiting for the transfer.
Best Wishes |
|
|
Cheick Guest
|
spi? |
Posted: Tue Jan 04, 2005 2:01 pm |
|
|
that made 2 months that I is caught the head with spi I seek the explanation of spi mode with two pic there are somebody to help me? |
|
|
|
|
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
|