Timer1 woes en PIC12F629

0

Estoy intentando hacer parpadear un LED con la interrupción de desbordamiento del Temporizador 1 en un PIC12F629, pero todo lo que obtengo es un valor BAJO constante en el pin GPIO. Estoy usando un oscilador de cristal de 32.768kHz con tapas de carga de 82pF y una tapa de filtro de 0.1uF en Vdd y Vss. El pin GPIO para el LED está configurado para hundirse (ánodo atado alto, cátodo a GPIO a través de la resistencia).

Lo tenía todo funcionando cuando utilizaba el oscilador interno (4MHz) pero no tuve suerte con el cristal LP. Estoy bastante seguro de que no es un problema de hardware, ya que pude hacer que funcionara (con la configuración de cristal LP) usando la función __delay_ms () integrada de MPLAB. También verifiqué el pin LED GPIO con un analizador lógico para asegurarme de que el LED no estaba parpadeando más rápido de lo que podía percibir. Aquí están mis fragmentos de código de varios archivos .h y .c:

#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;
    }
}

De la hoja de datos , aquí está el flujo de señales de Timer1:

Enmiscálculos,conelpreescaladoconfiguradoen1,utilizandountemporizadorde16bitsyuncristalde32.768kHz,eltemporizadordebedesbordarsecada2segundos.¿Algunaideadedóndevoymal?

EDITAR:Oh,oh,hayuna errata para Timer1 :(

EDIT2: Se corrigieron los cálculos en el párrafo anterior (olvidé invertir los 0.5Hz para obtener 2 segundos).

    
pregunta calcium3000

2 respuestas

1

Lo descubrí! Utilicé el reloj del sistema (F_osc / 4 en el diagrama de bloques) en lugar del propio oscilador LP, ya que configuré la frecuencia del sistema a 32.768 kHz:

T1CONbits.TMR1CS = 0;   // clock source = F_osc/4

No estoy seguro si es un error de noob usar el oscilador LP para el Timer1 cuando el reloj del sistema también lo está usando, o si hice algún otro supuesto / código incorrecto. Tampoco conseguí que la corrección en la errata (EJEMPLO 1) funcionara, así que no estoy reclamando la victoria completa. ¡Pero funciona!

EDITAR: y para calmar la ansiedad, también utilicé tapas de 22pF en el cristal.

    
respondido por el calcium3000
0

82 pF en un cristal de 33 kHz es demasiado alto. Lee la hoja de datos del cristal.

    
respondido por el Olin Lathrop

Lea otras preguntas en las etiquetas