# Microchip PIR register?

#### spinnaker

Joined Oct 29, 2009
7,837
My datasheet says about the PIR registers:

Interrupt flag bits are set when an interrupt
condition occurs, regardless of the state of
its corresponding enable bit or the Global
Interrupt Enable bit, GIE (INTCON<7>)

Am I reading this correctly that it says that interrupts do not need to be enabled at all? That the interrupt occurs regardless if interrrupts are enabled when the event occurs?

Joined Apr 16, 2011
377
No.

The FLAG will be set whenever an interrupt CONDITION occurs, but there will be no interrupt.

There will be no actual interrupt unless you set the corresponding interrupt enable bit AND GIE.

This allows simple polling, without the need for interrupts.

Hope this helps

#### spinnaker

Joined Oct 29, 2009
7,837
Thanks for the clarification. So the flag is set when an interrupt occurs regardless i interrupts are enabled or not?

Is that a correct statement?

This has to do with this thread.

#### kubeek

Joined Sep 20, 2005
5,626
Thanks for the clarification. So the flag is set when an interrupt occurs regardless i interrupts are enabled or not?
The interrupt doesn't occur - the main thread just keeps going. The flag is set when the event happens, and it is up to you if you react by reading it once in a while or set up an interrupt routine to handle it by setting the appropriate bits.

#### spinnaker

Joined Oct 29, 2009
7,837
The interrupt doesn't occur - the main thread just keeps going. The flag is set when the event happens, and it is up to you if you react by reading it once in a while or set up an interrupt routine to handle it by setting the appropriate bits.
So then the flag is set when the event occurs regardless of any interrupt settings, correct?

Joined Apr 16, 2011
377
correct

#### Jon Wilder

Joined Oct 25, 2011
23
PIR1 (Peripheral Interrupt flag Register 1) contains only flags for on chip peripherals which can generate interrupts. PIE1 (Peripheral Interrupt Enable register 1) contains the control bits which enable/disable each peripheral interrupts.

The interrupt flags in register PIR1 always get set/cleared when the condition to set the interrupt is met regardless of if interrupts are enabled or not. However, the program counter will not jump to the interrupt vector UNLESS the corresponding interrupt enable bit is set. But the interrupt flags are always available for polling regardless of the state of the interrupt enable bits.

In addition to having to have the corresponding enable bit in PIE1 set, flags PEIE and GIE in register INTCON also must be set in order to enable peripheral interrupts.

#### John P

Joined Oct 14, 2008
1,763
One point to note is that if you choose to poll the interrupt flags in the PIR register, your code is responsible for clearing them. If you don't make that happen, the flag simply stays set, and you'll keep detecting it. That's especially true if the program needs to start looking for a response to some particular event. So you check the relevant bit in the PIR register, and it's set. But it could have been made to set an hour ago or a week ago. What you need to do, to check for events after a certain time, is clear the flag when you start looking for the event.

#### spinnaker

Joined Oct 29, 2009
7,837
One point to note is that if you choose to poll the interrupt flags in the PIR register, your code is responsible for clearing them. If you don't make that happen, the flag simply stays set, and you'll keep detecting it. That's especially true if the program needs to start looking for a response to some particular event. So you check the relevant bit in the PIR register, and it's set. But it could have been made to set an hour ago or a week ago. What you need to do, to check for events after a certain time, is clear the flag when you start looking for the event.
It's not my code that it is doing it, it is Microchip's SPI library code.

And yes it is clearing the flag. I am trying to figure out why SPI is not working on the chip.

Nothing at all is being sent to the port. See above for another thread link for details.

I have two chips with similar features 18f26j53 and 18f27j53 and they both do not function on SPI. Yet I have a 18f14k22 that works just fine.

#### Jon Wilder

Joined Oct 25, 2011
23
It's not my code that it is doing it, it is Microchip's SPI library code.

And yes it is clearing the flag. I am trying to figure out why SPI is not working on the chip.

Nothing at all is being sent to the port. See above for another thread link for details.

I have two chips with similar features 18f26j53 and 18f27j53 and they both do not function on SPI. Yet I have a 18f14k22 that works just fine.
How are you setting up your MSSP hardware SFRs on both chips? Can you post the init code that sets them both up here?

#### spinnaker

Joined Oct 29, 2009
7,837
How are you setting up your MSSP hardware SFRs on both chips? Can you post the init code that sets them both up here?

I am using Microchip's SPI library.

Here is their OpenSPI code.

void OpenSPI1( unsigned char sync_mode, unsigned char bus_mode, unsigned char smp_phase)
{
SSP1STAT &= 0x3F; // power on state
SSP1CON1 = 0x00; // power on state
SSP1CON1 |= sync_mode; // select serial mode
SSP1STAT |= smp_phase; // select data input sample phase

switch( bus_mode )
{
case 0: // SPI1 bus mode 0,0
SSP1STATbits.CKE = 1; // data transmitted on rising edge
break;
case 2: // SPI1 bus mode 1,0
SSP1STATbits.CKE = 1; // data transmitted on falling edge
SSP1CON1bits.CKP = 1; // clock idle state high
break;
case 3: // SPI1 bus mode 1,1
SSP1CON1bits.CKP = 1; // clock idle state high
break;
default: // default SPI1 bus mode 0,1
break;
}

SSP1CON1 |= SSPENB; // enable synchronous serial port
}

Here is the WriteSPI

unsigned char WriteSPI1( unsigned char data_out )
{
unsigned char TempVar;
unsigned char TempVar2;

TempVar = SSP1BUF; // Clears BF
PIR1bits.SSP1IF = 0; // Clear interrupt flag
SSP1CON1bits.WCOL = 0; //Clear any previous write collision
SSP1BUF = data_out; // write byte to SSP1BUF register
if ( SSP1CON1 & 0x80 ) // test if write collision occurred
return ( -1 ); // if WCOL bit is set return negative #
else
//while( !SSP1STATbits.BF ); // wait until bus cycle complete
return 0;
do
{
TempVar2= !PIR1bits.SSP1IF;

} while(TempVar2); // wait until bus cycle complete
return ( 0 ); // if WCOL bit is not set return non-negative#
}

As I said above the library works fine on a 18f14k22. But that is a one port chip. The 18f26j53 and 18f27j53 have two SPI ports. Port 1 is hardwired to pins while port can be sent to programmable pins.

#### thatoneguy

Joined Feb 19, 2009
6,359
Is SSP1IE (PIE1.3) enabled anywhere?

#### Jon Wilder

Joined Oct 25, 2011
23
Also, it doesn't appear that you're setting one up as SPI Master while setting the other PIC up as SPI Slave.

#### spinnaker

Joined Oct 29, 2009
7,837
Is SSP1IE (PIE1.3) enabled anywhere?

No interrupt needs to be generated so the bit does not need to be enabled. The flag is set regardless of interrupt settings when the byte is transmitted.

The issue is that it is not being transmitted. No data, no clock nothing.

#### spinnaker

Joined Oct 29, 2009
7,837
Also, it doesn't appear that you're setting one up as SPI Master while setting the other PIC up as SPI Slave.

This is done in the aguments of OpenSPI.

I open the port with:

OpenSPI(SPI_FOSC_64, MODE_00, SMPEND);

this works fine on a 18f14k22 but not the 18f26j53.

#### thatoneguy

Joined Feb 19, 2009
6,359
This is done in the aguments of OpenSPI.

I open the port with:

OpenSPI(SPI_FOSC_64, MODE_00, SMPEND);

this works fine on a 18f14k22 but not the 18f26j53.
Are you sure you are setting up and monitoring the right SPI port? You only had one to choose from with the 14k22, this one has 2, with re-assignable pins for I/O.

It's probably a default setting hidden in the works, like the comparators disabling ports when they first are bumped into.

I went down half of the datasheet, but now that I look, I was looking at the 14k22 sheet, and not the 26j53 sheet.

Please copy/paste all your j53code in one post here so switching windows isn't needed, or is the other thread for the j53?

Do you have a PICKit 2? Does the PICKit 3 in debug mode give you any hints? Are you trying to send or receive (That's how confused I've gotten now), what are you trying to communicate with addess, and leading or trailing edge trigger needed? Do either SSP1BUF or SSP2BUF have anything in them?

#### spinnaker

Joined Oct 29, 2009
7,837
Are you sure you are setting up and monitoring the right SPI port? You only had one to choose from with the 14k22, this one has 2, with re-assignable pins for I/O.

It's probably a default setting hidden in the works, like the comparators disabling ports when they first are bumped into.

I went down half of the datasheet, but now that I look, I was looking at the 14k22 sheet, and not the 26j53 sheet.

Please copy/paste all your j53code in one post here so switching windows isn't needed, or is the other thread for the j53?

Do you have a PICKit 2? Does the PICKit 3 in debug mode give you any hints? Are you trying to send or receive (That's how confused I've gotten now), what are you trying to communicate with addess, and leading or trailing edge trigger needed? Do either SSP1BUF or SSP2BUF have anything in them?
Sorry somehow the two threads kind if got merged.

In theroy I should not need to do anything expect call OpenSPI and WriteSPI. That is assuming there are no bugs on the Microchip code.

Ihave the PicKit3. I am trying to send. Good tip on looking at the special function registers. I'll take a look. Should the transmit buffer always hold the last byte written to it or will it zero itself out?

#### thatoneguy

Joined Feb 19, 2009
6,359
Nevermind, all that was from the wrong datasheet.

Closing all but the j53 and starting over....

Last edited:

#### thatoneguy

Joined Feb 19, 2009
6,359
Here is the code you are calling with:
Rich (BB code):
#pragma config WDTEN = OFF
#pragma config XINST = OFF
#pragma config OSC = INTOSC

OpenSPI1(SPI_FOSC_4, MODE_00, SMPEND);
WriteSPI1(255);
Init code from what I've found, but LATx and TRISx bits weren't set, don't assume defaults, that gets me in trouble a lot.

Only sending a literal 255 on bus.

Rich (BB code):
void OpenSPI1( unsigned char sync_mode, unsigned char bus_mode, unsigned char smp_phase)
{
SSP1STAT &= 0x3F; // power on state
SSP1CON1 = 0x00; // power on state
SSP1CON1 |= sync_mode; // select serial mode
SSP1STAT |= smp_phase; // select data input sample phase

switch( bus_mode )
{
case 0: // SPI1 bus mode 0,0
SSP1STATbits.CKE = 1; // data transmitted on rising edge
break;
case 2: // SPI1 bus mode 1,0
SSP1STATbits.CKE = 1; // data transmitted on falling edge
SSP1CON1bits.CKP = 1; // clock idle state high
break;
case 3: // SPI1 bus mode 1,1
SSP1CON1bits.CKP = 1; // clock idle state high
break;
default: // default SPI1 bus mode 0,1
break;
}

SSP1CON1 |= SSPENB; // enable synchronous serial port
}
Here is where it is getting stuck, at the "while( !SSP1STATbits.BF); near the end of the 2nd function from the Microchip Library routine, it appears to have been changed from the library version, which I don't have handy, please post the unmodified library code for this part:
Rich (BB code):
unsigned char WriteSPI1( unsigned char data_out )
{
unsigned char TempVar;
unsigned char TempVar2;

TempVar = SSP1BUF; // Clears BF
PIR1bits.SSP1IF = 0; // Clear interrupt flag
SSP1CON1bits.WCOL = 0; //Clear any previous write collision
SSP1BUF = data_out; // write byte to SSP1BUF register
if ( SSP1CON1 & 0x80 ) // test if write collision occurred
return ( -1 ); // if WCOL bit is set return negative #
else
//while( !SSP1STATbits.BF ); // wait until bus cycle complete
return 0;
do
{
TempVar2= !PIR1bits.SSP1IF;
} while(TempVar2); // wait until bus cycle complete
return ( 0 ); // if WCOL bit is not set return non-negative#
}
The Line: SSP1BUF = data_out; // write byte to SSP1BUF register loads 255 into SSP1BUF, does that show up in debugging?

Am interested in original WriteSPI1 library code, couldn't find it in either thread.

Here is the datasheet checklist for transmitting SPI:
A typical SPI serial port initialization process follows:
• Initialize the ODCON3 register (optional open-drain output control)
• Initialize the remappable pin functions (if using MSSP2, see Section 10.7 “Peripheral Pin Select (PPS)”)
• Initialize the SCKx/LAT value to the desired Idle SCKx level (if master device)
• Initialize the SCKx/PCFGx bit (if in Slave mode and multiplexed with the ANx function)
• Initialize the SCKx/TRIS bit as output (Master mode) or input (Slave mode)
• Initialize the SDIx/PCFGx bit (if SDIx is multiplexed with the ANx function)
• Initialize the SDIx/TRIS bit
• Initialize the SSx/PCFG bit (if in Slave mode and multiplexed the with ANx function)
• Initialize the SSx/TRIS bit (Slave modes)
• Initialize the SDOx/TRIS

• Initialize the SSPxSTAT register
• Initialize the SSPxCON1 register
• Set the SSPEN bit to enable the module

With the parts in bold, I'm wondering if the right pins are being looked at. The datasheet I have is stamped "Preliminary", so the default pins might have changed?