interrupt, xc8, pic18

Discussion in 'Embedded Systems and Microcontrollers' started by bug13, Mar 24, 2015.

  1. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Hi guys

    I am coming from AVR. In AVRs, I can have multiple interrupt source in different interrupt function.
    Code (Text):
    1. ISR(Pin_Change_Vector_vect)
    2. {
    3.    //do stuff;
    4. }
    5.  
    6. ISR(ADC_Vector_vect)
    7. {
    8.    //do stuff;
    9. }
    10. ISR(Timer1_Vector_vect)
    11. {
    12.    //do stuff;
    13. }
    So in pic18 with xc8 complier, I am under the impression I am only allow one interrupt function.
    Code (Text):
    1. void interrupt some_interrupt(void)
    2. {
    3.   if (Timer1_interrupt_flag) {
    4.   //do stuff;
    5.   return;
    6.   }
    7.  
    8.   if (ADC_interrupt_flag) {
    9.   //do stuff;
    10.   return;
    11.   }
    12.  
    13.   if (Pin_change_interrupt_flag) {
    14.   //do stuff;
    15.   return;
    16.   }
    17. }
    But Can I do something like these?
    Code (Text):
    1. void interrupt Pin_Change_interrupt(void)
    2. {
    3.     if (ping_change_flag)
    4.     //do stuff;
    5. }
    6.  
    7. void interrupt Timer1_interrupt(void)
    8. {
    9.     if (timer1_flag)
    10.     //do stuff;
    11. }
    12.  
    13. void interrupt ADC_interrupt(void)
    14. {
    15.     if (ADC_flag)
    16.     //do stuff;
    17. }
    Thanks a lot guys!!
     
  2. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    AVR has a vectored interrupt configuration, where PIC has one or two (depending in the applicability of hardware prioritized interrupts).

    In general, there is only one location the PC is loaded with when an interrupt is fired, from there, the processor checks interrupt sources in turn, according to how your ISR is set up.

    That is one of the major drawbacks of PICs, in my opinion, though it is rarely much of an issue.

    Edit: So your code would likely be of the form:
    Code (Text):
    1.  
    2. void interrupt ISR(void)
    3. {
    4.    if (ping_change_flag)
    5.    {
    6.        //do stuff;
    7.    }
    8.    if (timer1_flag)
    9.    {
    10.      //do stuff;
    11.    }
    12.    if (ADC_flag)
    13.    {
    14.      //do stuff;
    15.    }
    16. }
    17.  
     
    ErnieM and bug13 like this.
  3. JohnInTX

    Moderator

    Jun 26, 2012
    2,340
    1,022
    To add to what tshuck noted, PIC18s can be used in a priority interrupt mode which has 2 vectors (0008h and 0018h). To use the priority mode you 1) provide 2 interrupt routines, one for high and one for low priority and 2) again how tshuck shows, combine all of your interrupt flag test-service routines into one or the other prioritized interrupt service routine. The compiler will sort out the context saving but to make it all work, your code 3)must set IPEN (interrupt priority enable - usually in RCON) and assign high or low priority to each active interrupt (in the various IPRx registers).
    INTCON works a bit differently in the priority mode - bit 40h is not the global enable for low priority interupts (GIEL) and 80h is the global enable for ALL interrupts (high and low prio).

    Other than that, have at it. The general admonition to keep PIC interrupt services short goes double for high prio interrupts. Also, keep them simple to avoid long context switches/code duplication because the PIC doesn't support re-entrancy.

    The compiler may advise you that it is handling fast-stack errata issues. Good, let it. Be glad you don't have to.

    Have fun!
     
    bug13 likes this.
Loading...