jueves, 11 de febrero de 2021

Interrupción por TMR1 con reloj secundario (SOSC) en PIC24

Llegué a este problema al tratar de utilizar el módulo RTCC, el cual requiere un cristal secundario de 32.768 kHz, porque me di cuenta de que no estaba seguro si el reloj secundario estaba funcionando en primer lugar. El programa que voy a comentar en esta entrada me permitió resolver los errores que estaba comentiendo. Empezando por los capacitores. Para el cristal de 32.768 kHz deben de ser de entre 5 y 12 pF (los de 10 pF me funcuinaron bien):
Estoy utilizando el compilador XC16 y el PIC24FJ32GB002. En la página 115 de su datasheet se menciona que esta familia es más suceptible al ruido por lo que podría dar problemas al usar un protoboard y hay que tener cuidado al diseñar una aplicación en PCB (acercar lo más posible el cristal a los pines y tener capacitores de desacople entre Vcc y GND). El programa es muy secillo y ya está probado en circuito fisico en una placa diseñada para una aplicación de sensado remoto en cavernas sumergidas. Lo que hace togglear un led cada segundo. Si les funciona es casi seguro que es un error de conexión o problemas de capacitancias parásitas.
/*
* File: main.c
* Author: Rodolfo Escobar
*
* Created on 10 de febrero de 2021, 09:44 AM
*/
//--- Bits de configuración ---
#pragma config POSCMOD = XT // Oscilador primario en modo XT
#pragma config FNOSC = PRIPLL // Oscilador primaro con PLL
#pragma config PLL96MHZ = ON // PLL activado
#pragma config PLLDIV = DIV2 // Entrada de 8MHz
#pragma config RTCOSC = SOSC // RTCC usa Osc secundario (SOSC))
#pragma config SOSCSEL = SOSC // Pines de Oscilador Secundario en modo SOSC
#pragma config FWDTEN = OFF // Timmer de Watchdog desactivado
#pragma config JTAGEN = OFF // Puerto JTAG desactivado
//-------------------------------
#include <p24FJ32GB002.h>
#include "xc.h"
#define FCY 16000000UL
#include "libpic30.h"
void gpio_init(void);
// Interrupción TMR1
void __attribute__((interrupt, auto_psv)) _T1Interrupt (void){
_T1IF = 0; // Limpiar bandera irq
LATBbits.LATB9 ^= 1; // Toggle del LED
}
int main(void) {
//----- Setup -----
gpio_init();
//----- SOSC
OSCCONbits.SOSCEN = 1; // Habilitar SOSC
__delay_ms(250); // Tiempo de estabilización
//----- TMR1
T1CON = 0x00; // Detiene temporizador
T1CONbits.TCS = 1; // Entrada por SOSC/T1CK (pag. 150) (32.768 kHz)
T1CONbits.TCKPS = 0b00; // Prescaler 1:1 (pag. 130)
TMR1 = 0x00; //Limpia el regitro de temporizador
PR1 = 32768; //Carga el periodo de 1 segundo
IPC0bits.T1IP = 0x01; //Prioridad de interrupción
IFS0bits.T1IF = 0; //Limpia bandera de periodo
IEC0bits.T1IE = 1; //Habilita la interrupción por TMR1
T1CONbits.TON = 1; //Inicia TMR1
//-----------------
while(1){} // Loop
return 0;
}
void gpio_init(void)
{
TRISBbits.TRISB9 = 0; // B9 como salida (LED_STATUS) (18)
}
view raw main.c hosted with ❤ by GitHub

No hay comentarios: