Salut,
J'ai besoin dans un projet de connecter plusieurs microcontroleurs avec une laison SPI.
Pour faire des test j'utilise pour le moment simplement 3 16f88 avec un master et 2 slaves, ça fait un moment que je cherche a faire fonctionner l'affaire mais je n'arrive pas a mettre la main sur le problème :le fonctionnement est completement eratique, les microcontroleurs se bloquent dans la fonction de transfert pour le master et dans l'interruption pour les esclaves...
Le maitre dois passer 4 octets a chaque esclaves, j'utilise CCS voila mon code:
/*****************MASTER :*********************/
/////////////////// les fusibles
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES IESO //Internal External Switch Over mode enabled
#use delay(clock=8000000)
/////////////////// les reglages dans le main
setup_adc_ports(NO_ANALOGS|VSS _VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_MASTER|SPI_L_TO_ H|SPI_CLK_DIV_16);
setup_timer_0(RTCC_INTERNAL|RT CC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1) ;
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(OSC_8MHZ|OSC_ INTRC);
set_tris_b (0b00000010); // B1 en entrée pour SDI
//////////////////// Ma fonction de transfert
void Envoyer(void)
{
// comme il y aura plus d'esclaves ensuite je prefere utiliser une boucle pour les selectionner
for(D1=0;D1<2;D1++)
{
if(D1==0) // selectionne l esclave
output_high(PIN_B6);
else
output_high(PIN_B7);
// Envoie les données octet par octet a l'esclave
for(D2=0;D2<4;D2++)
{
spi_write(info[D1][D2]);
}
output_low( PIN_B6 ); // deselectionne l'esclave
output_low( PIN_B7 ); // deselectionne l'esclave
}
}
}
/*****************SLAVE :*********************/
/////////////// Les fusibles
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES IESO //Internal External Switch Over mode enabled
#use delay(clock=8000000)
#use fast_io (ALL)
/////////////// les reglages dans le main
setup_adc_ports(NO_ANALOGS|VSS _VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_SLAVE|SPI_L_TO_H );
setup_timer_0(RTCC_INTERNAL|RT CC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1) ;
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ|OSC_ INTRC);
set_tris_a (0b00000000); // tout en sorties
set_tris_b (0b11000010); // B1,B7 et B6 en entrée (SDI et capteurs)
//////////////////Mon interruption
#int_SSP
void SSP_isr(void)
{
Ordre=spi_read(); // Enregistre l'ordre en premier
while(!spi_data_is_in());
info1=spi_read(); // puis les 3 infos
while(!spi_data_is_in());
info2=spi_read();
while(!spi_data_is_in());
info3=spi_read();
}
Voila, j'ai vraiment passé beaucoup de temps la dessus à essayer de regler le problème seul, je pense que mon soucis vient principalement d'un manque de connaissance du fonctionnement réel des routines SPI de ccs.
Malheureusement j'ai des partiels cette semaine et je n'aurais plus l'occasion avant un certain temps d'avancer mon projet
Donc si quelqu'un a une connaissance des ces routines de ccs et trouve mon/mes erreurs je lui en serait éternellement reconnaissant (sisi!)
Merci d'avance a ceux qui ont lu j'usque ici![]()
-----