Interrupt not working on PIC 12F629

Find out how to setup your programmer's software and how to solve many common problems.

Moderator: phalanx

Post Reply
happy_biker
Posts: 1
Joined: Sun Nov 13, 2016 4:54 pm

Interrupt not working on PIC 12F629

Post by happy_biker » Sun Nov 13, 2016 5:47 pm

Hello. I'm learning to program mid-range PICs by following the gooligum tutorials and everything has been working well until now.

I'm trying to make a led blink at exactly 1Hz using timer0 and interrupts. The device I'm using is the PIC 12F629.

Timer0 should overflow every 250 clocks (250us), and a variable is used to count the number of overflows until it reaches 2000 (2000*250us = 0.5s), when GP1 is toggled.

But when I try to simulate the code, nothing happens. I suspect I'm forgeting some simple detail, but a couple of days have passed and I'm still stuck.

Can anyone help me? Thank you very much.

BTW, I'm using MPLAB X (v3.40), XC8 compiler (v1.38), and Proteus 8 for simulation.

Code: Select all

// CONFIG
#pragma config FOSC = INTRCCLK // Oscillator Selection bits (INTOSC oscillator: CLKOUT function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = ON         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 4000000 // oscillator frequency for _delay()

/*******GLOBAL VARIABLES******/
volatile union{             //shadow copy of GPIO
uint8_t port;
struct{
    unsigned    GP0:1;
    unsigned    GP1:1;
    unsigned    GP2:1;
    unsigned    GP3:1;
    unsigned    GP4:1;
    unsigned    GP5:1;
    };
} sGPIO;

/*******MAIN PROGRAM******/
void main(){
    
    //Intialisation
    
        //configure port
        GPIO=0;                         //clear GPIO
        sGPIO.port=0;                   //clear sGPIO
        TRISIO=0b111101;                //GP1 (only) as output
        CMCON=0b00000000;               //turn off comparator
    
        //configure timer0
        OPTION_REGbits.T0CS=0;          //select timer mode
        OPTION_REGbits.PSA=1;           //no prescaler
        
        //enable interrupts
        INTCONbits.T0IE=1;              //enable Timer0 interrupt
        INTCONbits.GIE=1;               //enable global interrupt
        
        
    //main loop
    for (;;){
        GPIO=sGPIO.port;                //continually copy shadow GPIO to port
    }
}

/*******INTERRUPT SERVICE ROUTINE******/
void interrupt isr (void){
    
    // TMR0 overflows every 250 clocks = 250 us
    // Flashes LED at 1 Hz by toggling on every 2000th interrupt
    // (every 500 ms)
    
    static uint16_t cnt_t0=0;       //timer0 count variable
    
    TMR0+=256-250+3;                //add offset value to timer0
    INTCONbits.T0IF=0;              //clear interrupt flag
    
    ++cnt_t0;                       //increment interrupt count (every 250us)
    if(cnt_t0===2000){              //if count overflow (2000=500000/250)
        cnt_t0=0;                   //reset count
        sGPIO.GP1=~sGPIO.GP1;       //toggle LED (via shadow register)
    }
    
}

User avatar
phalanx
Non-SFE Guru
Posts: 1980
Joined: Sun Nov 30, 2003 8:57 am
Location: Candia, NH

Re: Interrupt not working on PIC 12F629

Post by phalanx » Mon Nov 14, 2016 7:17 am

Hi happy_biker,

First off, I want you to know that I've never made use of XC8 on such a small PIC so I'm not readily familiar with any nuances related to that arrangement. For parts that small, I always use straight assembly. I also have no experience with Proteus at any level.

That said, the only thing that catches my eye is this line in your ISR: if(cnt_t0===2000)

I would have expected XC8 to spit out an error but it may be trying to assign the result of the comparison to cnt_t0 which would always be false so the IF statement would never be true. Try getting rid of one of the equal signs and see if that makes a difference.

-Bill

User avatar
phalanx
Non-SFE Guru
Posts: 1980
Joined: Sun Nov 30, 2003 8:57 am
Location: Candia, NH

Re: Interrupt not working on PIC 12F629

Post by phalanx » Mon Nov 14, 2016 7:41 am

I tried building your code in MPLAB with XC8 and as I suspected, it spit out an error about your if(cnt_t0===2000) line. After changing it to "==" for a proper comparison, everything seemed to run properly in the MPLAB simulator.

-Bill

Post Reply