4
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ Even if it's an edge triggered interrupt, you should clear the flag in the handler. \$\endgroup\$ – pjc50 Apr 18 '13 at 16:32
  • \$\begingroup\$ Please edit your original post and let us see the code for spi_data_is_in() Is that a function written by you, or is it supplied by the compiler itself ? \$\endgroup\$ – User.1 Apr 19 '13 at 17:34
  • \$\begingroup\$ @User.1: spi_data_is_in() is a library functions but it's literally reading SSPBUF \$\endgroup\$ – vsmGuy Apr 19 '13 at 18:23
  • \$\begingroup\$ My smarts are on the PIC24, so throw my ideas away if they don't fit here; but where are you initializing the SPI module ? On the PIC24 I had to do peripheral pin select. I don't see that here. I will assume that the library functions are checking the SPIxBUF and SPIxSTAT registers properly. Endless nulls and the like are characteristic behaviors of a device that was not initialized properly. \$\endgroup\$ – User.1 Apr 19 '13 at 20:03
1
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.