TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: vra en 27 de Enero de 2020, 19:15:10
-
Hola a todos, tengo un problema aquí, estoy usando el timer 1 del PIC24FJ256GA106 en Proteus configurado con el oscilador externo, he leído unas cuantas veces toda la configuración que tengo para hacer funcionar el timer 1 y luego generar la interrupción respectiva pero el timer 1 simplemente no se incrementa. Entiendo que Proteus ignora cualquier circuito de reloj conectado a sus entradas de reloj por diseño y se ajusta a las propiedades de configuración del modelo, es decir, cambias la frecuencia con un campo pero igualmente debes configurarlo todo en el código que estás haciendo.
Al seguir los pasos tal y como aparecen en el manual del dispositivo y de referencia para los timers no logro nada, simplemente mi código se queda esperando eternamente a que pase lo que nunca pasará, que se desborde la bandera T1IF porque como dije, TMR1 no se incrementa, a continuación el código:
Los bits de configuración para el reloj están como sigue:
#pragma config POSCMOD = HS // Primary Oscillator Select (EC oscillator mode selected)
#pragma config IOL1WAY = ON // IOLOCK One-Way Set Enable bit (Write RP Registers Once)
#pragma config OSCIOFNC = OFF // Primary Oscillator Output Function (OSCO functions as CLKO (FOSC/2))
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor (Both Clock Switching and Fail-safe Clock Monitor are disabled)
#pragma config FNOSC = PRI // Oscillator Select (Secondary oscillator (SOSC))
#pragma config IESO = ON // Internal External Switch Over Mode (IESO mode (Two-speed start-up) enabled)
el archivo de cabecera para configuración de los relojes "sistema.h" del micro está como sigue:
#ifndef SISTEMA_H
#define SISTEMA_H
#include <xc.h> // include processor files - each processor file is guarded.
/*Definiciones de datos para desbloquear OSCCONh*/
#define SOSCENH 2
#define SOSCEND 0
/*Bit de habilitación de cambio de oscilador OSWEN*/
#define OSWENI 1
/*Definición de prototipos de funciones para el control del oscilador*/
void Tipo_Osc(unsigned short reloj); /* Función para configurar el tipo de
* reloj a utilizar.*/
void Sec_Osc(unsigned short secosc); /* Función para habilitar el uso del
* oscilador secundario.*/
#endif /* SISTEMA_H */
el archivo fuente para configuración de los relojes "sistema.c" del micro está como sigue:
#include "sistema.h"
void Tipo_Osc(unsigned short reloj)
{
__builtin_write_OSCCONH(reloj); /* Función para configurar el tipo de reloj a
* a utilizar.*/
}
void Sec_Osc(unsigned short secosc) /* Función para habilitar el uso del
* oscilador secundario. */
{
__builtin_write_OSCCONL(secosc);
}
mi archivo fuente de configuración del timer 1 "temporizadores.h" para generar el ciclo es el siguiente:
#ifndef TEMPORIZADORES_H
#define TEMPORIZADORES_H
#include <xc.h> // include processor files - each processor file is guarded.
void Ciclo_Timer1(unsigned int tempo1, unsigned int conf1);/* Prototipo de
* función para configurar el
* funcionamiento del timer 1. */
void Inicia_Ciclo_Timer1(void); /* Prototipo de función para iniciar el
* funcionamiento del timer 1. */
void Detiene_Ciclo_Timer1(void); /* Prototipo de función para detener el
* funcionamiento del timer 1. */
mi archivo fuente de configuración del timer 1 "temporizadores.c" para generar el ciclo es el siguiente:
#include "temporizadores.h"
#include "sistema.h"
/* Implementación de las funciones para la configuración de los temporizadores*/
void Ciclo_Timer1(unsigned int tempo1, unsigned int conf1) /* Función para la */
{ /* configuración del timer 1. */
Sec_Osc(SOSCENH); /* No se inicia el timer 1 en esta */
T1CON = 0; /* ción para dejar al usuario decidir */
TMR1 = 0; /* cuando encenderlo. */
T1CON = conf1; /* Está configurado para contar 100ms */
PR1 = tempo1*0x0ccd; /* y se usará para hacer el reloj en */
} /* tiempo real. */
void Inicia_Ciclo_Timer1(void) /* Inicia el timer 1. */
{
T1CONbits.TON = 1;
}
void Detiene_Ciclo_Timer1(void) /* Detiene el timer 1. */
{
T1CONbits.TON = 0;
}
finalmente en mi archivo main tengo lo siguiente:
int main(void) {
Tipo_Osc(PROSC);
Sec_Osc(SOSCENH);
Confi_E_S();
Inicia_Interr();
Ciclo_Timer1(100,0b0000000000000010);
PORTDbits.RD11 = 1;
Inicia_Ciclo_Timer1();
while(!IFS0bits.T1IF);
PORTDbits.RD11 = 0;
Detiene_Ciclo_Timer1();
while(1);
return 0;
}
Casi lo olvido...mi archivo de cabecera "interrup.h" para la configuración de las interrupciones es como sigue:
#ifndef INTERRUP_H
#define INTERRUP_H
#include <xc.h>
#include "globales.h"
/* Definición de constantes a usar en las interrupciones. */
void Inicia_Interr(void); /* Prototipo de función para configurar e
* iniciar las fuentes de interrupción. */
/* Prototipos de función para manejar las fuentes de interrupción */
void __attribute__((interrupt(no_auto_psv))) _T1Interrupt(void);/* Prototipo de
* función para manejar la
* interrupción del timer 1. */
void __attribute__((interrupt(no_auto_psv))) _T2Interrupt(void);/* Prototipo de
* función para manejar la
* interrupción del timer 2. */
void __attribute__((interrupt(no_auto_psv))) _CNInterrupt(void);/* Prototipo de
* función para manejar la
* interrupción por notificación
* de cambio en los pines
* seleccionados. */
#endif /* INTERRUP_H */
mi archivo de fuente "interrup.c" para la configuración de las interrupciones es como sigue:
#include "interrup.h"
void Inicia_Interr(void) /* Función para configurar e iniciar
* las fuentes de interrupción. */
{
IEC0bits.T1IE = 1; /* Configuración de las interrupciones*/
IPC0bits.T1IP = 1; /* para el timer 1. */
IFS0bits.T1IF = 0;
IEC0bits.T3IE = 1; /* Se habilita la interrupción */
/* para el timer de 32 bits, se */
IPC2bits.T3IP = 1; /* establece la prioridad de la */
IFS0bits.T3IF = 0; /* interrupción en 1 y se borra la */
/* la bandera del timer de 32 */
/* bits. */
IEC1bits.CNIE = 1; /* Se habilitan los pines CN62 a CN65 */
IPC4bits.CNIP = 2; /* para detectar el cambio de estado, */
IFS1bits.CNIF = 0; /* esto es, los Puerto E,4 a Puerto */
CNEN4 = 0xc000; /* E,7 para detectar la tecla */
CNEN5 = 0x0003; /* presionada. También se configuró la*/
/* prioridad de la interrupción por */
/* notificación de cambio de estado en*/
/* 2, un nivel más alta que la del */
/* temporizador. */
}
/* Funciones para el manejo de interrupciones */
void __attribute__((interrupt(no_auto_psv))) _T1Interrupt(void)/* Función para*/
{ /* manejo de la interrupción del */
/* timer 1, para usarlo como ciclo de */
IFS0bits.T1IF =0; /* trabajo del sistema. */
}
pero como el timer 1 no se incrementa entonces no entra en la rutina de interrupción para el timer 1.
al final no tengo idea que por qué no me quiere funcionar.
Podría alguien ayudarme con esto?, gracias de antemano por la ayuda brindada.