I am coding a SPI slave using a PIC16F877A in CCS C and need to be aware when the SS line (pin 7) goes from high (idle) to low (active) as information from the master is framed as a stream of bytes with the leading byte (first byte after SS goes active) telling me what the remaining bytes are for.
I have shorted SS (from master) to INT(pin 33) and written this:
#include <16F877A.h>
#device adc=16
#device *=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(clock=20000000)
#use rs232(baud=57600,parity=N,xmit=PIN_C6,rcv=PIN_C7, ERRORS)
// TODO: add a 100ohm resistor between the SS pin and the chip select output of the master microcontroller // Clock base Sample on
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H) // high trailing edge
volatile int1 slave_cs_enabled = false; //has the slave STB been enabled?
//#PRIORITY EXT, SSP
#PRIORITY INT_EXT, INT_SSP
#INT_EXT
void slave_cs_isr()
{
slave_cs_enabled = true;
}
//#INT_SSP
void main()
{
unsigned int8 data = 0;
enable_interrupts(INT_EXT);
ext_int_edge( H_TO_L );
clear_interrupt(INT_EXT); //if you read the data sheet, you will
enable_interrupts(GLOBAL);
//Now the code will call the interrupt in the rising edge.
setup_spi(SPI_SLAVE | SPI_MODE_3);
while(1) {
if(slave_cs_enabled)
{
slave_cs_enabled = false;
printf("STB\n\r");
}
if(spi_data_is_in())
{
data = spi_read();
printf("%X\n\r", data);
}
}
}
All I get after STB are "00". Literally zeros.
This behavior remains unchanged even if I physically disconnect pin 33 from pin 7, pointing to an issue in my code.
When I take out the STB logic (including disabling the interrupt code), then I get stream of bytes but that is not useful to me as I now don't know where a stream starts and ends.
Help!
Best Answer
You should check the settings of the TRISB register. Read section 4.2 of this document (http://ww1.microchip.com/downloads/en/DeviceDoc/39582C.pdf). It explains how the TRIS (tristate) registers control the input/output behavior of the PIC16F family. If TRISB[0] is set to 0 then the RB0/INT pin will be outputting low and overriding the interrupt mechanism.
I've lost many hours to that little register in the past.