////////////////////////////////////////////////////////////////////////////////////
//
// Midiendo_un_pulso_2_CCP.c
//
// SERIE: "Técnicas en C" para el Foro TODOPIC
//
// (c) 10.2006 by RedPic
//
// Propósito: Medir el tiempo que permanece un pulso en alto
//
// Condiciones de Test: Inyección por RB3 de una señal de 2 Khz (0.5 ms de periodo)
//
// Técnica Empleada: Detectar mediante la Interrupción CCP (Compare)
// un flanco de subida de un pulso, guardar el estado
// de TMR1, detectar a continuación el siguiente
// flanco de bajada, guardar el nuevo estado de TMR1,
// realizar las substracción de ambos para obtener el
// tiempo que permanece en alto y transmitir mediante
// el puerto RS232 a petición.
//
////////////////////////////////////////////////////////////////////////////////////
#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 FLASH Output_Toggle(LED) // Defino la funcion Flash de monitor
float const uSxTick = 0.2; // Microsegundos por Tick de TMR1 a 20 Mhz
////////////////////////////////////////////////////////////////////////////////////
//
// Variables en RAM
//
////////////////////////////////////////////////////////////////////////////////////
char cRec=0x00; // Último caracter recibido via serie
char Command=0x00; // Comando a procesar
int1 flagToggleFlanco=0; // Flag para cambiar de flanco
int16 t1=0x00,t2=0x00,tt=0x00; // Variables para guardar estados de ...
float st=0.0; // TMR1 en cada flanco y hacer la resta
int1 flagHayDatos=0; // Flag para indicar que ya hay datos de ..
// dos flancos (de subida y bajada)
int1 flagHayTransmitir=0; // Flag para indicar que hay datos para ...
// Transmitir al PC.
////////////////////////////////////////////////////////////////////////////////////
//
// Interrupción por Recepción Serie RS232
//
////////////////////////////////////////////////////////////////////////////////////
#int_rda
void handle_rda_int(){
if(kbhit()){ // Si hay algo pdte de recibir ...
cRec
=getc(); // lo recibo sobre cRec ... if(cRec!=0x00){ // Si es distinto de \0 ...
Command=ToUpper(cRec); // cargo cRec sobre Command para procesarlo
} // pasándolo a Mayúsculas para no confundir.
}
}
////////////////////////////////////////////////////////////////////////////////////
//
// Interrupción por Externa por Cambio de Flanco en RB0
//
////////////////////////////////////////////////////////////////////////////////////
#int_ccp2
void handle_ccp2_int(){
if(flagToggleFlanco==0){ // He recibido Flanco de Subida
t1=get_timer1(); // Guardo en t1 el valor de TMR1 al Flanco de Subida
setup_ccp2(CCP_CAPTURE_FE); // Configuro para capturar siguiente flanco de Bajada
flagToggleFlanco=1; // Indico que el siguiente flanco será de Bajada
} else { // He recibido Flanco de Bajada
t2=get_timer1(); // Guardo en t2 el valor de TMR1 al Flanco de Bajada
setup_ccp2(CCP_CAPTURE_RE); // Configuro para capturar siguiente flanco de subida
flagToggleFlanco=0; // Indico que el siguiente flanco será de Subida
set_timer1(0); // Reinicio TMR1
if(flagHayDatos==0){ // Si los datos anteriores han sido procesados ...
flagHayDatos=1; // Indico que ya hay nuevos datos de flancos para calcular
}
}
FLASH; // Reproduzco la entrada mediante un LEd en E0;
}
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
set_tris_c(0b10000000); // Habilito como entrada RC7 para canal RS232
setup_ccp2(CCP_CAPTURE_RE); // Configuro captura de 1er flanco de subida
flagToggleFlanco = 0; // inicializo el Flag para cambiar de flanco
enable_interrupts(int_rda); // Habilito las interrupciones necesarias
enable_interrupts(int_ccp2);
enable_interrupts(global);
printf("\r\nMidiendo un pulso : CCP\r\n"); printf("By Redpic para Foro TODOPIC\r\n\n");
do {
if(flagHayDatos==1){ // Detecto que ya hay datos de flancos ...
if(t2 > t1){ // Compruebo que estoy en la misma vuelta de TMR1
tt = t2 - t1; // Calculo en Tick's de TMR1 el tiempo entre flancos
st = uSxTick * tt; // Calculo en uS el tiempo.
flagHayTransmitir=1; // Indico que tengo nuevo valor para transmitir
}
flagHayDatos=0; // Indico que ya han sido procesados los datos.
}
if(Command!=0x00){ // Si he recibido un comando vía Serie ...
if(Command=='T'){ // Si el comando es 'T' (Transmite) ...
if(flagHayTransmitir==1){ // Si hay algo pendiente de transmitir ...
printf("Ticks %Lu - %Lu = %Lu = %3.1fuS \r\n",t2
,t1
,tt
,st
);
flagHayTransmitir=0; // Indico que ya he transmitido lo pendiente.
}
}
Command=0x00; // Indico que ya he procesado el comando.
}
} while (TRUE);
}