Microchip PIR register?

Discussion in 'Embedded Systems and Microcontrollers' started by spinnaker, Nov 19, 2011.

  1. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    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?
     
  2. hexreader

    Active Member

    Apr 16, 2011
    250
    82
    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
     
  3. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    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.

    http://forum.allaboutcircuits.com/showthread.php?t=62205

    The flag is never being set. More info in the thread.
     
  4. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    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.
     
  5. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    So then the flag is set when the event occurs regardless of any interrupt settings, correct?
     
  6. hexreader

    Active Member

    Apr 16, 2011
    250
    82
    correct :)
     
  7. Jon Wilder

    New Member

    Oct 25, 2011
    23
    1
    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.
     
  8. John P

    AAC Fanatic!

    Oct 14, 2008
    1,634
    224
    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.
     
  9. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    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.
     
  10. Jon Wilder

    New Member

    Oct 25, 2011
    23
    1
    How are you setting up your MSSP hardware SFRs on both chips? Can you post the init code that sets them both up here?
     
  11. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016

    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.
     
  12. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Is SSP1IE (PIE1.3) enabled anywhere?
     
  13. Jon Wilder

    New Member

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

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016

    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.
     
  15. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016

    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.
     
  16. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    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?
     
  17. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    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?
     
  18. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Nevermind, all that was from the wrong datasheet.

    Closing all but the j53 and starting over....
     
    Last edited: Nov 21, 2011
  19. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Here is the code you are calling with:
    Code ( (Unknown Language)):
    1.  
    2.  
    3. #pragma config WDTEN = OFF
    4. #pragma config XINST = OFF
    5. #pragma config OSC = INTOSC
    6.  
    7. OpenSPI1(SPI_FOSC_4, MODE_00, SMPEND);
    8. WriteSPI1(255);
    9.  
    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.

    Code ( (Unknown Language)):
    1.  
    2. void OpenSPI1( unsigned char sync_mode, unsigned char bus_mode, unsigned char smp_phase)
    3. {
    4.     SSP1STAT &= 0x3F; // power on state
    5.     SSP1CON1 = 0x00; // power on state
    6.     SSP1CON1 |= sync_mode; // select serial mode
    7.     SSP1STAT |= smp_phase; // select data input sample phase
    8.  
    9.     switch( bus_mode )
    10.     {
    11.         case 0: // SPI1 bus mode 0,0
    12.             SSP1STATbits.CKE = 1; // data transmitted on rising edge
    13.             break;
    14.         case 2: // SPI1 bus mode 1,0
    15.             SSP1STATbits.CKE = 1; // data transmitted on falling edge
    16.             SSP1CON1bits.CKP = 1; // clock idle state high
    17.             break;
    18.         case 3: // SPI1 bus mode 1,1
    19.             SSP1CON1bits.CKP = 1; // clock idle state high
    20.             break;
    21.         default: // default SPI1 bus mode 0,1
    22.             break;
    23. }
    24.  
    25. SSP1CON1 |= SSPENB; // enable synchronous serial port
    26. }
    27.  
    28.  
    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:
    Code ( (Unknown Language)):
    1.  
    2. unsigned char WriteSPI1( unsigned char data_out )
    3. {
    4.     unsigned char TempVar;
    5.     unsigned char TempVar2;
    6.  
    7.     TempVar = SSP1BUF; // Clears BF
    8.     PIR1bits.SSP1IF = 0; // Clear interrupt flag
    9.     SSP1CON1bits.WCOL = 0; //Clear any previous write collision
    10.     SSP1BUF = data_out; // write byte to SSP1BUF register
    11.     if ( SSP1CON1 & 0x80 ) // test if write collision occurred
    12.             return ( -1 ); // if WCOL bit is set return negative #
    13.     else
    14.     //while( !SSP1STATbits.BF ); // wait until bus cycle complete
    15.     return 0;
    16.     do
    17.     {
    18.         TempVar2= !PIR1bits.SSP1IF;
    19.     } while(TempVar2); // wait until bus cycle complete
    20.     return ( 0 ); // if WCOL bit is not set return non-negative#
    21. }
    22.  
    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?
     
Loading...