Problema con el modulo CCP para generar una señal periódica con el P16F628A

Necesito realizar un código en C con el MPLAB para el compilador PICC de HI-TECH que genere una señal cuadrada de 38 KHz.

Para ello me he planteado utilizar el módulo CCP del pic que estoy utilizando (el P16F628A) . La idea es cargar en el registro CCP1H:CCP1L el valor correspondiente a la mitad del ciclo y configurar el CCP en modo comparación para que cuando el Timer1 llegue a ese valor se resetee el valor de TMR1 y se genere una interrupción que me permita cambiar la salida de 0 a 1 o de 1 a 0 según corresponda.

El oscilador debería de funcionar a 4 MHz y la frecuencia de instrucción una cuarta parte, 1MHz o un 1us. Como la mitad del periodo es aproximadamente 13us pues ese es el valor que cargo en el CCP1.

El problema es que mi código no genera nada y no se donde me equivoco! Alguien podría decirme donde me estoy equivocando?

#include <stdio.h>
#include <htc.h>

#define SALIDA RB5


unsigned short valor = 13;


/* service routine for ccp interrupt */
void
interrupt CCP_isr(void) {
TMR1ON = 0; // detenemos el TIMER1
TMR1IF = 0; // limpiamos la bandera
SALIDA = !SALIDA; // cambia el valor de la salida
TMR1ON = 1; //volvemos a ponerlo a contar
}

void
main(void) {
// initialize timer 1 and CCP module;
OSCF = 1; // oscilador interno a 4 MHz
CCP1CON = 0b00001011; // módulo CCP en modo comaparación y reseteando el Timer1
T1CON = 0; // preescalado 1:1 modo oscilador OFF, TMR1CS = O internal clock..
TRISB5 = 0;
OSCF = 1; // oscilator to 4 MHz (not to 38 KHz)
CCP1IE = 1; // activamos interrupciones para el módulo CCP1
CCPR1L = (char)(valor & 0xFF);
CCPR1H = (char)(valor >> 8);

GIE = 1; // habilitamos las interrupciones globales
TMR1IF = 0;
TMR1ON = 1; //comienza a contar

for(;;)
continue; // let interrupt do its job
}
 
Lo primero que veo es que sería más fácil usar el modo PWM (me fijo, y te digo como )que el modo de comparación.
Lo segundo es que estás usando el TMR1 cuando para el módulo se usa el TMR2.
Asi que lo 1ro que tenes para hacer es configurar el TMR2 en vez del TMR1, y si no te anda acá estamos.

Saludos

------------------

Edición:

error! el TMR2 se usa para el módulo PWM, pero el TMR1 para comparación y captura.
Aunque creo que la cuestión también viene por el lado de los tiempos de interrupción como te dije acá.

Probá con PWM y te olvidás de las interrupciones!.

PWM period =(PR2+1)*4*Tosc * PRE_TMR2

para una señal de 38 KHz el periodo es = 26,3 us -> 26 us

en tal caso deberá ser

PRE_TMR2=1 y PR2 = 25

Para el ciclo de trabajo (0.5 para que sea cuadrada -> 13):

Ciclo trabajo = (CCPR1L:CCP1CON<5:4>) x Tosc x PRE_TMR2 (tiempo en nivel alto en realidad)

Un detalle interesante, fijate que el ciclo de trabajo (o mejor dicho el tiempo en nivel alto, puse ciclo de trabajo por traducción literal de la hoja de datos) podés manejar múltiplos de Tosc, y no de 4 Tosc.
Es decir, tenés resolución de 1/4 MHz = 250 ns ; el cuádruple que utilizando un timer.

Entcones para 13 us sería CCPR1L:CCP1CON<5:4> = 52.

Fuentes: hoja de datos y Compare/Capture/PWM (CCP) - PICmicro Mid-Range MCU Family
---------------------
Contanos como te fué, saludos
 
Atrás
Arriba