Generando un pulso. 2ª Parte. Onda simétrica con INTCCP en modo CompareA.- Conceptos involucrados:Seguimos dándole vueltas al mismo concepto que en todas las
Técnicas en C anteriores. Si lo deseáis podéis repasar esto mismo en cualquiera de ellas.

Volvemos a generar un pulso de Periodo
T con dos semiperiodos iguales, simétrico, y de unos 2 Khz de frecuencia: unos 0.25 ms en alto y otros 0.25 ms en bajo, total 0.5 ms de periodo.
B.- Técnica a Aplicar:Para generar el
periodo T de nuestro pulso vamos a utilizar de nuevo el
módulo CCP del que disponen la gran mayoria de los PIC's, tanto los de la serie 18F como los 16F.
Recordemos: En la Técnica
Midiendo un pulso. 2ª Parte. Tiempo en Alto con INTCCP hacíamos uso de este mismo módulo utilizando su modo
Capture en el que cuando detectábamos un flanco externo se nos
capturaba el valor en ese momento del
TMR1. Jugando con los sucesivos valores obteníamos la duración del pulso.
En ésta técnica que ahora describimos vamos a hacer lo diametralmente opuesto: Vamos a utilizar el
CCP en modo
Compare para que el CCP vaya
comparando automáticamente el valor de
TMR1 con un
valor de referencia que le damos,
CCP_x, y en cuanto lo alcance se realice la
conmutación del Pin asociado a él y nos dispare la Petición de Servicio de Interrupción (ISR)
INT_CCPx correspondiente.
En el código de esta interrupción volvemos a hacer lo mismo pero configurando el
Compare para que cuando TMR1 alcance el valor de referencia
conmute nuestro Pin CCP al estado contrario.
Si
ambos valores de TMR1 de referencia, para el Compare a Alto y el Compare a bajo,
son iguales tendremos un tren de
pulsos simétricos, están el mismo tiempo en alto que en bajo, o sea que tienen un Duty Cycle del 50%. En caso contrario estarán mas tiempo en un estado que en otro y será una onda asimétrica, o sea que tendrá un Duty Cicle distinto del 50%.
El
periodo será la suma de ambos tiempos, el que permanece en estado alto mas el que está en estado bajo.
Calculando cuidadosamente dichos tiempos podremos generar una onda del periodo que deseamos.
Pondremos a 0 siempre
TRM1 y cargaremos
CCP_x con el número de
Ticks de TMR1 en que deseamos que se dispare nuestra conmutación/interrupción.
C.- Implementación en C:Para implementar nuestro
Código en C vamos a centrarnos en los puntos que hemos descrito en la sección anterior.
Para
configurar la interrpción CCP utilizaremos lo siguiente:
GeSHi (c):
setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configuro CCP2 en modo COMPARE cambiando a Alto
enable_interrupts(int_ccp2); // Habilito la interrpción INT_CCP2
enable_interrupts(global); // Habilito las interrupciones necesarias
Con esta configuración inicial podemos ya escribir nuestra
rutina ISR que es muy simple ya que únicamente selecciona mediante un
flag si debe el siguiente cambio es a
Alto o a Bajo y colocar el tiempo en que deseamos en que esto se produzca:
GeSHi (c):
#int_ccp2
void handle_ccp2_int(){
if(++flagConmuta==1){
setup_ccp2(CCP_COMPARE_CLR_ON_MATCH); // Configura CCP2 en modo COMPARE cambiando a Bajo
} else{
setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 en modo COMPARE cambiando a Alto
}
CCP_2=0; // Pongo a cero el valor a comparar ...
set_timer1(0); // y el TMR1.
CCP_2 = 1250; // Quiero que se dispare cada 0.25 ms ...
// luego pongo los Ticks de TMR1 para ese tiempo.
}
Notad que estoy trabajando con una configuración particular a la que me sujeta el Hardware específico del que dispongo: El módulo CCP2 y un cuarzo de 20 Mhz.
Con un Cristal de 20 Mhz los cálculos me indican que el número de Ticks de TMR1 necesarios para realizar una conmutación cada 0.25 ms es de 1250 (0.00025 / (1/ FOSC)*4)
Con todo esto el programa completo para nuestro
Generar una Onda Cuadrada Simétrica de 2 Khz de Frecuencia queda así:
GeSHi (c):
////////////////////////////////////////////////////////////////////////////////////
//
// Generando_un_pulso_6_INTCCP.c
//
// SERIE: "Técnicas en C" para el Foro TODOPIC
//
// (c) 11.2006 by RedPic
//
// Propósito: Generar un pulso de 2 Khz (0.5 ms de periodo)
//
// Técnica Empleada: Habilitar INTCCP para conmutar el PIN CCP2 cada semiperiodo
// utilizando el recurso CCP en modo compare.
//
////////////////////////////////////////////////////////////////////////////////////
#include <18f4550.h>
#fuses HS,MCLR,CCP2B3,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
////////////////////////////////////////////////////////////////////////////////////
//
// Defines y Constantes
//
////////////////////////////////////////////////////////////////////////////////////
#define LED PIN_E0 // Defino el Pin del Led
#define OUT PIN_B3
////////////////////////////////////////////////////////////////////////////////////
//
// Variables en RAM
//
////////////////////////////////////////////////////////////////////////////////////
int1 flagConmuta=0;
////////////////////////////////////////////////////////////////////////////////////
//
// Interrupción CCP por Compare TMR1
//
////////////////////////////////////////////////////////////////////////////////////
#int_ccp2
void handle_ccp2_int(){
if(++flagConmuta==1){
setup_ccp2(CCP_COMPARE_CLR_ON_MATCH); // Configura CCP2 en modo COMPARE cambiando a Bajo
} else{
setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 en modo COMPARE cambiando a Alto
}
CCP_2=0; // Pongo a cero el valor a comparar ...
set_timer1(0); // y el TMR1.
CCP_2 = 1250; // Quiero que se dispare cada 0.25 ms ...
// luego pongo los Ticks de TMR1 para ese tiempo.
Output_Toggle(LED); // Monitorizo visualmente con el PIN de Led;
}
////////////////////////////////////////////////////////////////////////////////////
//
// Main
//
////////////////////////////////////////////////////////////////////////////////////
void main() {
////////////////////////////////////////// INICIALIZACIONES GENERALES
delay_ms(333); // Espero a que todo se estabilice e ...
disable_interrupts(global); // Inicializo el Micro y ...
disable_interrupts(int_timer1); // deshabilitando todo lo no necesario ...
disable_interrupts(int_rda);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_0(RTCC_OFF);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(FALSE);
delay_ms(333);
/////////////////////////////////////////// INICIALIZACIONES PERTINENTES A LA APLICACION
setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 en modo COMPARE cambiando a Alto
enable_interrupts(int_ccp2); // Habilito la interrpción INT_CCP2
enable_interrupts(global); // Habilito las interrupciones necesarias
printf("\r\nGenerando un pulso : INTCCP Compare\r\n");
printf("By Redpic para Foro TODOPIC\r\n\n");
do {
} while (TRUE);
}
D.- Ejemplo funcionando:Je, je, je La foto es la misma que en
Generando un pulso. 1ª Parte. Onda simétrica con INTRTCC ya que la única diferencia está en el Firmware del PIC: el resto visualmente y desde fuera es absolutamente igual.

Y esto es todo por hoy, amigos.

Mañana, más.