I am trying to setup the SPI1 port on my PIC24HJ206GP256 micro. I have set the SPI1CON1 control register with 0x0020, the SPI1STAT control register with 0x8000 (i.e. turn on the SPIEN), and SPI1CON2 = 0.

At the moment a simple write to the SPI1BUF is implemented like this:

 void writeSPI1(char data){
     _SPI1IF = 0;             //set interrupt flag to zero
     SPI1BUF = data;          //write data to SPI1BUF
     while( _SPI1IF == 0);    //wait to flag to go high

When the data is written, the SPI1IF should go high, but it never reaches this point so the program simply remains in the loop forever. So it seems no data will ever be clocked out of the SPI port through MOSI.

I have tried to make it work by setting TRISF = 0x0000, although I have read that the SPI port should take care of SPI pin configuration.

I am using a watch window to view the contents of the SPI1BUF.

I have tried with different settings within the control registers but have had no luck. Also have tried enabling the SPI1IF (IEC0: Interrupt Enable Control Register 0) and still the problem persists.

Are there any extra configurations I have forgotten, like some odd functionality of PORTF which takes precedence over the SPI port?


2 Answers 2


Use the SPI peripheral library, it'll make things much easier.

Check the data sheet for the alternative functions of the pins you are using. If they are shared with the ADC that will be the default function and you will need to enable them for digital I/O.

You should use the Microchip forums for this type of question, many more people there will be using the 16-bit PICs.


Have you tried polling on the SPI1STAT:SPITBF register instead of the SPI1IF? If the interrupt flag does not toggle when it should, does the SPI1STAT:SPITBF register toggle at all either? According to the data sheet that register should set when data is loaded into the TX buffer, via SPI1BUF, and clear when data exits the TX buffer and gets transmitted over the pin. For a first try, I'd just wait to see if SPI1STAT:SPITBF to goes to 0 after loading SPI1BUF. If you have on oscilliscope, that'd be a great way to see if anything is being transmitted over the output pins at all.

Also, where does the definition of _SPI1IF come from? If you're using MPLAB as your dev environment, make you use the register definitions from the chip header file. I'm wondering if _SPI1IF is even mapped to the correct register.

  • \$\begingroup\$ I concur. On a 16LF1825, I use SSPBUF = MyVal; to load the byte for sending, then while (!SSP1STATbits.BF); to wait for it to send. Works well. Pour over the datasheet... it's in there. \$\endgroup\$
    – rdtsc
    Dec 30, 2015 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.