have banging my head against the wall for 3 days trying to get some PIC16F876 code to work. I desperately need help in getting this working. About a year ago, a guy wrote some communication code to have 2 of these PICs talk to each other through the SPI channel. The code he wrote was really messy. When I recently needed to expand the code from sending 6 byte message sequences to 7 bytes it died. I believe this was due to how he tried to spin in the SPI ISR to recieve all 6 bytes. I couldn't figure out the new timings and I saw that everyone else seems to have nice and neat C code that takes care of everything without needing to worry about these timings. Just spi_write() and spi_read() and everyone is happy. So I have started with fresh code for the comms and have not got anything working yet. The chips are wired together properly to support communications because they have worked in the past. They are setup as a master/slave setup with the Slave Select wired in and a interupt driven Slave. Everything in the code looks normal and like it should work. But, the slave chip will always register a WCOL error. I have tried several difference methods to make this go away but I can't figure it out. The master always sees 0xFF when it gets data and the Slave always has 0x00 or 0xFF for data. Both chips are running and active since I can still communicate on the rs232 side and see the messages I expect. Any help would be greatly appreciated. Master: Code: #if defined(__PCM__) #include "16f876.h" #device ADC=10 #fuses HS,NOWDT,NOPROTECT #use delay (clock=20000000) #endif #use spi(master) #byte PORTB = 6 #define ALL_OUT 0 #BIT nSS = 0x06.0 #BIT T0IF = 0x0B.2 #BIT SPI_BF = 0x94.0 #BIT SPI_IF = 0xC.3 #BYTE SSPBUF = 0x13 void main() { // Setup the PIC setup_timer_2(T2_DIV_BY_4, 127, 1); setup_spi(spi_master | spi_H_to_L | spi_clk_div_64); set_tris_b(ALL_OUT); // set up the timer device for a 1224 Hz interrupt set_rtcc(0); setup_counters(RTCC_INTERNAL, RTCC_DIV_16); // Turn Everything on enable_interrupts(INT_TIMER0); enable_interrupts(GLOBAL); enable_interrupts(int_rda); delay_ms(1000); // Pause 1 second to let 232 chip get operational // Start Comms loop while( TRUE ) { // Time to SPI it up? if(spi_clock > 100) { // Transmit the data for(i=0; i<SPI_Channel_Size; i++) { nSS = 0; nSS = 1; SPI_IF = 0; SSPBUF = Outgoing_SPI_data[i]; while(!SPI_IF); Incomming_SPI_data[i] = SSPBUF; delay_ms(5); } nSS = 0; spi_clock = 0; } } } Slave: Code: #if defined(__PCM__) #include "16F876.h" #device ADC=10 #fuses HS,NOWDT,NOPROTECT #use delay(clock=20000000) #use spi(SLAVE) #endif #BIT T2IF = 0x0C.1 #BYTE SSPBUF = 0x13 #BIT SPI_BF = 0x94.0 #BIT SPI_IF = 0xC.3 #BYTE SSPCON = 0x14 #BIT SS_Active = 0x05.5 #int_ssp void spi_isr() { // Was orignally // Clear SSPCON // Read SSPBUF // Spin in loop waiting for additional 5 bytes and service timer too. // validate data // preload next message start if (SPI_BF) { Incomming_SPI_data[next_SPI_in] = SSPBUF; next_SPI_in = (next_SPI_in + 1) % SPI_Channel_Size; SSPBUF = Outgoing_SPI_data[next_SPI_in]; rcvd = 1; cnt ++; } if(SSPCON & 0x40) // Receive Overflow { SSPCON &= 0x3F; rcvd = 1; } if(SSPCON & 0x80) // Write collision { tmo = 1; SSPCON &= 0x3F; } SPI_IF = 0; } void main() { // Setup the PIC setup_adc (adc_off); set_tris_a (0x20); set_tris_b (0xFF); set_tris_c (0x9F); // set up the timer0 device for a 1124 Hz interrupt set_rtcc(0); setup_counters(RTCC_INTERNAL,RTCC_DIV_16); // Was originally //setup_timer_2 (T2_div_by_1, 50, 1); //setup_spi (spi_slave | spi_H_to_L | spi_clk_div_64); //SSPCON = (SSPCON & 0xFD); setup_timer_2 (T2_DIV_BY_4, 127, 1); setup_spi (spi_slave | spi_H_to_L); SPI_IF = 0; SPI_BF = 0; SSPBUF=Outgoing_SPI_data[0]; // Turn everything on enable_interrupts(INT_TIMER0); enable_interrupts(int_ssp); enable_interrupts(int_rda); enable_interrupts(GLOBAL); // Start Comms loop while( TRUE ) { ... } }