I'm attempting to blink an LED with the Timer1 overflow interrupt on a PIC12F629, but all I get is a constant LOW value on the GPIO pin. I'm using a 32.768kHz crystal oscillator with 82pF load caps and a 0.1uF filter cap across Vdd and Vss. The GPIO pin for the LED is set to sink (anode tied high, cathode to GPIO through resistor).
I had it all working when using the internal oscillator (4MHz) but haven't had any luck while using the LP crystal. I'm pretty sure it's not a hardware issue since I was able to get it to work (with the LP crystal setup) using MPLAB's built-in __delay_ms() function. I also checked the LED GPIO pin with a logic analyzer to make sure the LED wasn't just blinking faster than I could perceive. Here are my code snippets from several .h and .c files:
#include <xc.h>
// CONFIG register
#pragma config WDTE = OFF // turn off WDT
#pragma config FOSC = 0b000 // LP crystal
// Set up LP crystal GPIO
TRISIObits.TRISIO4 = 1;
TRISIObits.TRISIO5 = 1;
WPUbits.WPU4 = 0;
WPUbits.WPU5 = 0;
// Set up interrupts
TMR1H = 0;
TMR1L = 0;
PIR1bits.TMR1IF = 0;
PIE1bits.TMR1IE = 1;
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;
// Set up Timer1
T1CONbits.TMR1GE = 0;
T1CONbits.T1CKPS = 0b00; // prescaler = 1
T1CONbits.T1OSCEN = 0;
T1CONbits.nT1SYNC = 0;
T1CONbits.TMR1CS = 1;
T1CONbits.TMR1ON = 1;
// Set up GP2 (LED)
TRISIObits.TRISIO2 = 0;
WPUbits.WPU2 = 0;
GPIObits.GP2 = 0;
// Interrupt service routine
void interrupt isr(void)
{
if(PIR1bits.TMR1IF)
{
PIR1bits.TMR1IF = 0;
GPIObits.GP2 ^= 1;
}
}
From the datasheet, here's Timer1's signal flow:
From my calculations, with prescaler set to 1, using a 16-bit timer and a 32.768kHz crystal the timer should overflow every 2 seconds. Any ideas where I'm going wrong?
EDIT: Uh oh, there's an errata for Timer1 :(
EDIT2: Fixed the math in the above paragraph (forgot to invert the 0.5Hz to get 2 seconds).