TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: estalli2 en 27 de Octubre de 2010, 09:16:15
-
Hola Amigos,
estoy empezando a programar con ccs, y si bien voy a pasos pequeños me tope con un problema que seguramente debe ser algo sencillo. Estoy programando un medidor de frecuencia sencillo con el fin de solo conocer un poco mas de programación.
Pasa que estoy midiendo el tiempo de un periodo mediante la interrupcion del tmr1 de un pic 16f628a, ya lo he logrado, ahora quiero hacer la inversa del tiempo del periodo para obtener la frecuencia en el display pero no lo logro, o consigo valores que no son lo que da la formula matematica.
agrego el codigo:
#include <16f628a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#include<flex_lcd_2.c> //libreria manejo lcd
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) //manejo del RS232
int1 cambio=0;
int16 TFB;
float AP;
float BP;
int1 nuevopulso=0;
#int_ext
void funcion_ext_int(){ //Función Interrupción
if(cambio==1){ // Flanco de Subida
set_timer1(0); //Inicializa TMR1
ext_int_edge(0,L_TO_H); // habilito otra interrupcion
cambio=0; // Control de cambio de flanco.
nuevopulso=0;
} else { // Flanco de Bajada
TFB=get_timer1(); //Valor del Timer1 para el Flanco de bajada
set_timer1(0);
ext_int_edge(0,L_TO_H); //Configurar para flanco subida
cambio=1; //para contar otro periodo
nuevopulso=1; //para que habilite salida a pantalla
}
}
void main()
{
lcd_init();
setup_timer_1(T1_INTERNAL |T1_DIV_BY_1);
ext_int_edge(0,L_TO_H); // Configuro captura de 1er flanco de subida
enable_interrupts(int_ext); // Habilito las interrupciones necesarias
cambio=1; //primer cuenta ver interr
nuevopulso=0; //sacar a display off
TFB=0;
AP=0;
BP=0;
enable_interrupts(global);
do {
if(nuevopulso==1){ // me fijo y si es correcto saco a display
printf(lcd_putc,"\f"); //limpio pantalla
AP = 1/TFB; // frrecuencia en MHz
BP = TFB; //tiempo del periodo
printf(lcd_putc,"Frec%5f", AP); //Visualiza frecuencia en LCD
//printf(AP);
printf(lcd_putc,"\nTiemp%f", BP); //Visualiza tiempo en useg LCD
delay_ms(100);
nuevopulso=0; //Pulso medido
TFB=0;
cambio=1;
}
} while (TRUE); //Bucle Infinito
}
el programa espera el flanco de subida, interrumpe y pone el tmr1 a cero, espera el siguiente flanco, interrumpe y toma el valor de tmr1 y lo guarda en TFB y luego lo saca al display, y asi repite siempre.
EL valor del periodo lo saca perfectamente, no asi con la frecuencia.
Muchas gracias de antemano a todos! ;-)
-
yo lo he estado simulando, pero tienes razon muestra mal los valores en el display, lo que he notado es que la operacion matematica ap= 1/tfb no se realiza, pero no entiendo el porque, ya he probado agregarle tiempos... pero sigue sin hacer nada... voy a seguir probando haber que es lo que ocurre...
-
Hola, la variable AP es del tipo float, pero la variable TFB es del tipo int16. Al hacer la división 1/TFB la toma como una división entera, y no toma los decimales.
Para poder ralizar la división correctamente debes hacer un cast
AP = 1/ (float) TFB;
ó declarar la variable TFB como float. Con alguna de estas 2 soluciones debería mostrar el valor correcto de AP
Siempre hay que tener en cuenta con qué tipo de datos se está trabajando.
-
Hola, la variable AP es del tipo float, pero la variable TFB es del tipo int16. Al hacer la división 1/TFB la toma como una división entera, y no toma los decimales.
Para poder ralizar la división correctamente debes hacer un cast
AP = 1/ (float) TFB;
ó declarar la variable TFB como float. Con alguna de estas 2 soluciones debería mostrar el valor correcto de AP
Siempre hay que tener en cuenta con qué tipo de datos se está trabajando.
Es cierto!!! cosa de principiantes! ahora lo hago a ver que pasa!!! aviso en un rato! graciasssss!!!!!
-
Si señorrrr!!! :-/
era eso, defini como float a TFB y listo.
Muchas gracias a todos!, por si alguien quiere experimentar, les dejo el programa y la conexion para Isis.
Saludos!