| 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. 1ª Parte. Tiempo en Alto mediante INTEXT |
|
|
| 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(){ if(flagToggleFlanco==0){ // He recibido Flanco de Subida t1=get_timer1(); // Guardo en t1 el valor de TMR1 al Flanco de Subida 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 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 } } } |
||
|
| 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. } |
||
|
|
//////////////////////////////////////////////////////////////////////////////////// // // midiendo_un_pulso_1_intext.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 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, // 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,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 función 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 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_ext void handle_ext_int(){ if(flagToggleFlanco==0){ // He recibido Flanco de Subida t1=get_timer1(); // Guardo en t1 el valor de TMR1 al Flanco de Subida 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 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); /////////////////////////////////////////// INICIALIZACIÓN PERTINENTE A LA APLICACIÓN 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 : Width High\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); } |
||
|
|
|
|
Esta página se modificó el 27/12/2008
|