| PicManía by RedRaven |
Búsqueda personalizada
|
TÉCNICAS EN C |
||
|
|
|
Esta serie de contenidos titulada Técnicas en C pretende mostrar con ejemplos comentados la forma de implementar ciertos procesos muy usuales durante el uso de los Microcontroladores PIC de las series 16F y 18F. |
|
|
|
|
Midiendo un pulso. 4ª Parte. El pulso completo. El Periodo y la Frecuencia |
|
|
| A.- Conceptos involucrados: |
|
|
|
|
|
|
|
|
|
|
| B.- Técnica a Aplicar: |
|
|
|
|
|
Lo que vamos a realizar
exactamente es: |
|
|
|
|
|
|
|
| C.- Implementación en C: |
|
|
ext_int_edge(0,L_TO_H); // Configuro captura de 1er flanco de subida flagToggleFlanco = 0; // inicializo el Flag para cambiar de flanco enable_interrupts(int_ext); // Habilito las interrupciones necesarias enable_interrupts(global); |
||
|
|
| #int_ext void handle_ext_int(){ ++numFlancoQueLlega; // Cuento flanco que nos llega if(flagToggleFlanco==0){ // He recibido Flanco de Subida if(numFlancoQueLlega==1){ set_timer1(0); // Reinicio TMR1 t1=get_timer1(); // Guardo en t1 el valor de TMR1 al primer Flanco de Subida } if(numFlancoQueLlega==3){ t3=get_timer1(); // Guardo en t1 el valor de TMR1 al primer Flanco de Subida if(flagHayDatos==0){ // Si los datos anteriores han sido procesados ... flagHayDatos=1; // Indico que ya hay nuevos datos de flancos para calcular } } ext_int_edge(0,H_TO_L); // 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 ext_int_edge(0,L_TO_H); // Configuro para capturar siguiente flanco de subida flagToggleFlanco=0; // Indico que el siguiente flanco será de Subida } FLASH; // Reproduzco la entrada mediante un LEd en E0; if(numFlancoQueLlega==3){ numFlancoQueLlega=0; } } |
||
|
|
| if((t3>t2)&&(t2>t1)){ // Compruebo que estoy en la misma vuelta de TMR1 tth = t2 - t1; // Calculo en Tick's de TMR1 el tiempo en Alto ttl = t3 - t2; // Calculo en Tick's de TMR1 el tiempo en Bajo tt = tth + ttl; // Calculo en Tick's de TMR1 el Periodo del Pulso sth = uSxTick * tth; // Calculo en uS el tiempo en Alto. stl = uSxTick * ttl; // Calculo en uS el tiempo en Bajo. st = uSxTick * tt; // Calculo en uS el tiempo del Periodo. f = 1 / (st / 1000000); // Calculo la Frecuencia del pulso 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 ....... H %4Lu + L %4Lu = %4Lu\r\n",tth,ttl,tt); printf("uSegundos ... H %3.1f + L %3.1f = %3.1f F = %4.2f Hz\r\n\n",sth,stl,st,f); flagHayTransmitir=0; // Indico que ya he transmitido lo pendiente. } } Command=0x00; // Indico que ya he procesado el comando. } |
||
|
|
//////////////////////////////////////////////////////////////////////////////////// // // midiendo_un_pulso_4_complete.c // // SERIE: "Técnicas en C" para el Foro TODOPIC // // (c) 10.2006 by RedPic // // Propósito: Medir los tiempos en alto y bajo que permanece un pulso // // Condiciones de Test: Inyección por RB0 de una señal de 2 Khz (0.5 ms de periodo) // // Técnica Empleada: Detectar mediante la Interrupción Externa por RB0 // 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, // detectar a continuación un nuevo flanco de subida, // guardar nuevamente el estado de TMR1 y realizar la // correspondiente substracción de ellos para obtener // el tiempo que permanece en alto y bajo y transmitir // los resultados mediante el puerto RS232 a petición. // //////////////////////////////////////////////////////////////////////////////////// #include <18f4550.h> #fuses HS,MCLR,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 carácter recibido vía serie char Command=0x00; // Comando a procesar int8 numFlancoQueLlega=0; // Número de Flanco que llega int1 flagToggleFlanco=0; // Flag para cambiar de flanco int16 t1=0x00,t2=0x00,t3=0x00; // Variables para guardar estados de ... int16 tth=0x00,ttl=0x00,tt=0x00; // Timers y pulsos. float sth=0.0,stl=0.0,st=0.0,f=0.00; // Para hacer las restas oportunas en uS 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_ext void handle_ext_int(){ ++numFlancoQueLlega; // Cuento flanco que nos llega if(flagToggleFlanco==0){ // He recibido Flanco de Subida if(numFlancoQueLlega==1){ set_timer1(0); // Reinicio TMR1 t1=get_timer1(); // Guardo en t1 el valor de TMR1 al primer Flanco de Subida } if(numFlancoQueLlega==3){ t3=get_timer1(); // Guardo en t1 el valor de TMR1 al primer Flanco de Subida if(flagHayDatos==0){ // Si los datos anteriores han sido procesados ... flagHayDatos=1; // Indico que ya hay nuevos datos de flancos para calcular } } ext_int_edge(0,H_TO_L); // 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 ext_int_edge(0,L_TO_H); // Configuro para capturar siguiente flanco de subida flagToggleFlanco=0; // Indico que el siguiente flanco será de Subida } FLASH; // Reproduzco la entrada mediante un LEd en E0; if(numFlancoQueLlega==3){ numFlancoQueLlega=0; } } 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 ext_int_edge(0,L_TO_H); // 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_ext); enable_interrupts(global); printf("\r\nMidiendo un pulso : Periodo\r\n"); printf("By Redpic para Foro TODOPIC\r\n\n"); do { if(flagHayDatos==1){ // Detecto que ya hay datos de flancos ... if((t3>t2)&&(t2>t1)){ // Compruebo que estoy en la misma vuelta de TMR1 tth = t2 - t1; // Calculo en Tick's de TMR1 el tiempo en Alto ttl = t3 - t2; // Calculo en Tick's de TMR1 el tiempo en Bajo tt = tth + ttl; // Calculo en Tick's de TMR1 el Periodo del Pulso sth = uSxTick * tth; // Calculo en uS el tiempo. stl = uSxTick * ttl; // Calculo en uS el tiempo. st = uSxTick * tt; // Calculo en uS el tiempo. f = 1 / (st / 1000000); // Calculo la Frecuencia 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 ....... H %4Lu + L %4Lu = %4Lu\r\n",tth,ttl,tt); printf("uSegundos ... H %3.1f + L %3.1f = %3.1f F = %4.2f Hz\r\n\n",sth,stl,st,f); flagHayTransmitir=0; // Indico que ya he transmitido lo pendiente. } } Command=0x00; // Indico que ya he procesado el comando. } } while (TRUE); } |
||
|
|
|
|
Esta página se modificó el 27/12/2008
|