• AVR Freaks

Hot!Can some kind soul help me getting interrupts to work?

Author
NMNeil
New Member
  • Total Posts : 16
  • Reward points : 0
  • Joined: 2018/01/23 15:01:03
  • Location: 0
  • Status: offline
2020/08/06 20:30:09 (permalink)
0

Can some kind soul help me getting interrupts to work?

I'm sure I'm doing something wrong, but cannot for the life of me see what.
I’ve read the datasheet almost from cover to cover, scoured the internet, including this forum, changed the code till I’m blue in the face, but to no avail.
PIC12F1572 (Genuine one from Mouser), xc8 ver 2.20, MPLABX ver 5.3.
I’m learning, so this was a simple interrupt learning project. The LED will blink, and on the interrupt rising edge the LED would go off for 5 seconds, then the blink would start over again.
The blink works fine, but no matter what I do, the interrupt simply won’t work.
Reset pin is held high with a 10K resistor, RA2 is held high with another 10K and grounded when I push a button.
I set the config bits to use the internal clock, watchdog off and low voltage programming enabled.
 
#include <xc.h>
#define _XTAL_FREQ 4000000
void __interrupt() myInt();     //interrupt prototype (Tried moving it or not using it, but no difference)
 
void main(void)
{
    OSCCON = 0x68;                //internal clock set to 4Mhz
    TRISAbits.TRISA0 = 0;       //sets RA0 as output
    TRISAbits.TRISA2 = 1;       //sets RA2 as input
    INTCONbits.PEIE = 1;        //peripheral interrupts on
    INTCONbits.INTE = 1;        //external INT on
    INTCONbits.GIE = 1;         //global interrupts on
    OPTION_REGbits.INTEDG = 1;  //trigger on rising edge (Tried it on the falling edge but no change.)
    INTCONbits.INTF = 0;        //clear the interrupt flag   
 
 while(1)
 {       //simple blink program    
         LATAbits.LATA0 = 1;
        __delay_ms(500);
          LATAbits.LATA0 = 0;
        __delay_ms(500);     
 }
    return;
}
 
void __interrupt() myInt()
{
    if (INTCONbits.INTF == 1)   //make sure the flag is set
    {    LATAbits.LATA0 = 0;    //turn off the LED
        __delay_ms(5000);       //wait a while
        INTCONbits.INTF = 0;    //clear interrupt flag
        return;                         //back to blink
    }
}
 
I'm hoping someone in the know can point at my obvious mistake, because I can't see it.
#1

13 Replies Related Threads

    mbrowning
    USNA79
    • Total Posts : 1795
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: online
    Re: Can some kind soul help me getting interrupts to work? 2020/08/06 20:37:11 (permalink)
    +2 (2)
    Obvious mistake is that you haven’t set analog capable input pins to digital. All analog capable pins default to analog and the digital input buffer is turned off.
    #2
    ric
    Super Member
    • Total Posts : 28378
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/06 20:38:08 (permalink)
    +2 (2)
    You're not getting interrupts because pin RA2 is still in the default power up mode of "analog input".
    It's your job to switch any analog capable pins to digital mode if you want to use them as inputs.
    ANSELAbits.ANS2 = 0;    // switch RA2 to digital input

    will do the trick
     
    Also, you don't need a return inside the ISR.
    It's a really bad idea to have any time delay inside an ISR. I understand this is just a crude test to see if it's happening.
     
     
     
    post edited by ric - 2020/08/06 20:39:50

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #3
    mbrowning
    USNA79
    • Total Posts : 1795
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: online
    Re: Can some kind soul help me getting interrupts to work? 2020/08/06 20:41:01 (permalink)
    +1 (1)
    You also don’t need a prototype for the ISR.
    #4
    ric
    Super Member
    • Total Posts : 28378
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/06 20:43:30 (permalink)
    +1 (1)
    mbrowning
    You also don’t need a prototype for the ISR.

    Good point.
    Also, leave setting GIE until after ALL other initialisation has been completed.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    ric
    Super Member
    • Total Posts : 28378
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/06 20:58:10 (permalink)
    +2 (2)
    Try this:

    //CONFIG settings go here

    #include <xc.h>
    #define _XTAL_FREQ 4000000
     
    void main(void)
    {
        OSCCON = 0x68;              //internal clock set to 4Mhz
        LATA = 0;                   //Start all bits low
        TRISA = 0b111110;           //RA0 as output, all others as input
        ANSELA = 0b111011;          //RA2 is digital input
        OPTION_REGbits.INTEDG = 1;  //trigger on rising edge

        INTCONbits.PEIE = 1;        //peripheral interrupts on
        INTCONbits.INTE = 1;        //external INT on
        INTCONbits.INTF = 0;        //clear the interrupt flag   
        INTCONbits.GIE = 1;         //global interrupts on

     while(1)
     {       //simple blink program    
             LATAbits.LATA0 = 1;
            __delay_ms(500);
              LATAbits.LATA0 = 0;
            __delay_ms(500);     
     }
    }
     
    void __interrupt() myInt()
    {
        if (INTCONbits.INTF == 1)   //make sure the flag is set
        {    LATAbits.LATA0 = 0;    //turn off the LED
            __delay_ms(5000);       //wait a while
            INTCONbits.INTF = 0;    //clear interrupt flag
        }
    }


    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #6
    NMNeil
    New Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2018/01/23 15:01:03
    • Location: 0
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/07 05:31:04 (permalink)
    0
    Thank you, thank you, thank you. I didn't have much hair left to tear out and you saved the remainder for me.
    I wonder why it's not mentioned in the datasheet or on the Microchip developers page.
    https://microchipdeveloper.com/faq:31
    #7
    ric
    Super Member
    • Total Posts : 28378
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/07 05:49:02 (permalink)
    +1 (1)
    They screwed up.
    It is telling that the example ISR doesn't handle the INTF interrupt.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #8
    NMNeil
    New Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2018/01/23 15:01:03
    • Location: 0
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/07 08:29:08 (permalink)
    0
    Again many thanks.
    I amended the code as you all suggested, and it worked perfectly first time.
    When you explained, it was obvious that the pin should be set to digital for it to work, but re-reading the datasheet and the developers page for the INT and ANSELA registers, they make no mention that the ANSELA has to be set to digital for external interrupts to work. For a newbie, such as myself, I would never have worked it out on my own, it was only with the forum members help that I fixed the problem.
    Again thanks to you all, and boo hiss to Microchip.
     
    #9
    dan1138
    Super Member
    • Total Posts : 3843
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/07 08:55:19 (permalink)
    +1 (1)
    NMNeil
    I wonder why it's not mentioned in the datasheet ...

    PIC12(L)F1571/2 data sheet DS40001723D-page 111, section 11.3.6 ANALOG CONTROL, EXAMPLE 11-1: INITIALIZING PORTA, line: CLRF ANSELA ;digital I/O.

    It really important to look at an comprehend the examples in the data sheet.

    I suspect when what passes for Microchip technical writers today "improved" the document by making the examples "better" they got yelled at by the real engineers, a lot. After the acquisition of Atmel the new data sheet format has given them even more opportunities to "improve" the documentation by removing the ugly (useful) stuff.
    #10
    NMNeil
    New Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2018/01/23 15:01:03
    • Location: 0
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/07 09:13:03 (permalink)
    0
    You are correct, it's in the notes and I overlooked it.
    It would have been better in the notes at the bottom of page 74 for us newbies.

    Note 1: 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, of the INTCON register. User software should ensure the
    appropriate interrupt flag bits are clear prior to enabling an interrupt.
    2: Bit PEIE of the INTCON register must be set to enable any peripheral interrupt.
    3: The IOCIF Flag bit is read-only and cleared when all the Interrupt-On-Change flags in the IOCxF registers
    have been cleared by software.
    #11
    dan1138
    Super Member
    • Total Posts : 3843
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/07 09:32:42 (permalink)
    +1 (1)
    With regard to the enhanced mid-range controllers like the PIC12F1572 there are almost more exceptions than rules when interrupt flags are involved.
     
    These are just some of the traps for new players:
     
    The Interrupt-On-Change(IOC) flag in some controllers will not clear until the PORT has been read.
     
    The UART transmit interrupt flag is cleared only while the transmit shift register is full so this is always asserted when the transmitter is enabled.
     
    #12
    NMNeil
    New Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2018/01/23 15:01:03
    • Location: 0
    • Status: offline
    Re: Can some kind soul help me getting interrupts to work? 2020/08/07 09:47:45 (permalink)
    0
    I'm finding that out as I learn. mr green: mr green
     
    #13
    upand_at_them
    Super Member
    • Total Posts : 649
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: online
    Re: Can some kind soul help me getting interrupts to work? 2020/08/07 10:34:30 (permalink)
    +3 (3)
    dan1138After the acquisition of Atmel the new data sheet format has given them even more opportunities to "improve" the documentation by removing the ugly (useful) stuff.



    I opened a ticket, complaining about the loss of the index.  They pretty much said "Yeah, so?...Why do you want an index?"
    #14
    Jump to:
    © 2020 APG vNext Commercial Version 4.5