PIC32 Multiple interrupts issue

Discussion in 'Embedded Systems and Microcontrollers' started by kasula4, Apr 21, 2010.

  1. kasula4

    kasula4 Thread Starter New Member

    Apr 9, 2010
    I am trying to use multiple interrupts in PIC32 microcontroller. When I use 2 interrupts lets say UART and 1 timer the microcontroller is working fine but when I use UART and 2 timer interrupts the microcontroller freezes. I have the following code in the interrupts.

    #include "Tao4ch_defs.h"
    // UART 2 interrupt handler
    // it is set at priority level 2

    void __ISR(_UART_2A_VECTOR, ipl3) _U2ARXInterrupt(void)
    { char ch;

    IFS1bits.U2ARXIF = 0; // Reset the RX interrupt flag.

    ch = U2ARXREG;

    Char_in = ch;

    Char_cap = 1; // Flag to indicate a character has been received.
    // 0x0A is a line feed. Some terms attach linefeeds so must discard them.

    if (ch != 0x0D && ch != 0x0A) { // If the rx'd char is not 'enter' or lf

    Rx_buff [Rx_index] = ch; // load the rx buffer with the char and

    Rx_index++; // increment the index.

    if (Rx_index >= RX_BUF_LEN)

    Rx_index = 0;

    if (ch == 13) { // When the 'enter' char is received

    Rx_buff[Rx_index] = 0; // put a null char in the string.

    Rx_index = 0; // and reset the index.

    Com_flag = 1; // Com flag should be reset after the
    } // buffer has been read.
    // string is processed.


    // interrput code for the timer 1

    void __ISR( _TIMER_1_VECTOR, ipl2) _T1Interrupt( void)
    int i;

    asm("ei"); //To enable interrupts
    // clear interrupt flag and exit

    IFS0bits.T1IF = 0;

    sampleBuffer[sampleIndex].re = read_ext_adc1(5) - 25485; // read the ADC into the real part of the samplebuffer

    // increment the sampleIndex
    if (sampleIndex == (N-1))
    sampleIndex = 0;

    } // T3 Interrupt

    void __ISR( _TIMER_3_VECTOR, ipl1) _T3Interrupt( void)
    { asm("ei");

    IFS0bits.T3IF = 0;

    //do something


  2. rjenkins

    rjenkins AAC Fanatic!

    Nov 6, 2005
    Try to avoid doing any complex processing within an interrupt, keep it short so you do not have to re-enable interrupts while one is active.

    Another speed-up is to make buffers power-of-two lengths and simply do
    rx_index &= 0x1f; to limit the index to 0-31 or whatever.

    I usually poll any i/o within a timer routine, cycling fast enough to ensure no overruns.

    I'd generally run it at about 10KHz, but I have used in excess of 250KHz on PIC16.

    Examples, comments added for info:
    // Storage declarations
    int     cd_tbuf[32]; // The data buffer
    int     cd_tbufi; // Buffer Input pointer
    int     cd_tbufo; // Buffer Output pointer
    int     cd_tbufc; // Buffer Count
    // Initialisation
    void rs_clear(void) {
        rs_tbufi = 0;
        rs_tbufo = 0;
        rs_tbufc = 0;
    // Routine to buffer TX characters
    void rs_tput(int i) {
        rs_tbuf[rs_tbufi++] = i; // Store data, inc pointer
        rs_tbufc++; // Inc buffer count
        rs_tbufi &= 0x1f;  // Pointer roll-over to zero.
    // TX poll routine called from within RTC interrupt
    void rs_send(void) {
    // If nothing to send, quit.
        if(rs_tbufi == rs_tbufo) { 
            rs_tbufc = 0;
    // Otherwise, if UART is not busy,
        if(rs_tx_rdy())    {                
            putchar(rs_tbuf[rs_tbufo++]); // Send character & inc pointe
            rs_tbufo &= 0x1f; // Roll-over
            rs_tbufc--; // Dec buffer count
    (Note - naming - That's pulled out of a program that has multiple comms routines named with different prefixes, that particular one just happened to be rs_... ).
  3. BMorse

    BMorse Senior Member

    Sep 26, 2009
    Do you have Multi vector Interrupts Enabled??

    here is a code snippet I used with the Pic32 interrupts.....
    at the bottom of the code, you can see my Interrupt initialization routine where I enable the Multi vector interrupts..... and as RJenkins had said, try not to do too much in an interrupt routine, You could very well miss a different interrupt....
    // Interrupts
    #ifndef _bINT_HEADER_FILE
    #define _bINT_HEADER_FILE
    void __ISR( _RTCC_VECTOR,ipl1) RTCCInterrupt( void)
        SYS_MODE++;                //Increment SYS_MODE to reflect current state of system
        mRTCCClearIntFlag();    //Clear Interrupt Flag
    }//RTCC Interrupt
    void __ISR(_UART1_VECTOR,ipl2) IntUart1Handler(void)
        //is this an RX interrupt??
        if (mU1RXGetIntFlag())
        {//clear the RX interrupt flag
        }//RX Interrupt
        if (mU1TXGetIntFlag())
        {//we dont care for it so just clear it
        }//End TX Interrupt
    void __ISR( _EXTERNAL_2_VECTOR,ipl3) INT2InterruptHandler(void)    //PIR Sensor Interrupt
        asm ("ei");
            Motion=1;            //Set Flag
            Vanity_On=1;        //Set Flag
            mSSR1_ON();            //Turn On Vanity Light
            LOD=0;                //Reset Light On Delay
    }//End INT2
    void __ISR( _EXTERNAL_1_VECTOR,ipl5) INT1InterruptHandler(void)    //MPR084Q Interrupt Source, 
                                                                    //Not used right now, using polling method instead
        asm ("ei");
    }//End INT1
        mRTCCSetIntPriority(1);                //Set Real Time Clock And Calendar Priority Level
        mRTCCClearIntFlag();                //Clear RTCC Interrupt Flag
        mINT2SetIntPriority(3);                //Set Interrupt Priority for External Int Source 0    
        mINT1SetIntPriority(5);                //Set Interrupt Priority for External Int Source 1
        INTEnableSystemMultiVectoredInt();        //Enable Multi vectored Interrupts
        mINT2IntEnable(1);                //Enable External Interrupt 0
        mINT1IntEnable(1);                //Enable External Interrupt 1
    }//End Init Interrupts
    I also noticed when I was working with the Pic32, that you have to start with the lowest priority first..... if you notice in my code ipl1 is the first routine, all the way down to ipl5....

    B. Morse
    Last edited: Apr 22, 2010
  4. kasula4

    kasula4 Thread Starter New Member

    Apr 9, 2010
    Thanks for the replies. I have a question for BMORSE. I think IPL7 is the highest priority so I think asm(ei) should be used in lower priorities IPL(0) etc.., were you able to run the same code successfully.
  5. BMorse

    BMorse Senior Member

    Sep 26, 2009

    You are right ipl7 is the highest priority level, I used the asm (ei), just to make sure other interrupts are still enabled when entering that ISR.....

    And yes, the way I have the ISR's set up, seems to work very well for me....

    B. Morse