saludos pues estaba intentando realizar un tacometro para mi bicicleta, jeje (ya que no tengo auto
), jeje
y la idea que tengo es usar dos timers, el TMR0 para contar un segundo, y el TMR1 para contar los pulsos de un circuito que envie un cero o un uno cada vez qeu pase por un lugar en la rueda, el TMR1 será en realidad el contador de revoluciones en el segundo que cuenta el TMR0, una vez que pase el segundo del TMR0 captura lo que tiene el TIMER1 aprovechando que es de 16bits aguantará muchas vueltas en un segundo, en realidad 64k de vueltas como maximo, aunque agregando codigo se lograria más no hay problema, para probar solo cuento como máximo 64k. Una vez capturado puede facilmente llevarse a un LCD o a displays de Leds (que es mi caso, ya que en definitiva mi LCD no sirve
), la idea creo que está bien, o hay algo más qeu deba considerar??
y pues como pense que estaba bien, le puse manos a la obra, y pues parece que da, pero presenta algunos errores, solo estoy en torno a simulación, simulo como siempre en proteus 7.1 sp2, le pongo un generador de clock en el T1CKI, a la frecuencia que quiera, por ejemplo 60Hz, es decir 60 rps (revoluciones por segundo), ya que eso es lo que mediría con el TMR1, para llevarlo a rpm solo una división entre 60 y listo, en ese caso sería uno, y se ve bien el 1, pero si cambio la frecuencia a 120Hz, deberia leer 2, y en efecto veo un dos, pero solo un momento despues se va a 5, y no entiendo porque lo hace, y si pongo por ejemplo 60KHz de freceuncia, lo que deberia medir en realidad es 1000rpm, y me da como 1026 rpm; y en esos valores erroneos va oscilando, por ejemplo en que mide 1026 primero mide 1027 despues 1025 y recien se va quedando en 1026 o despues sigue oscilando, medio que tiene error, y nose muy bien porque puede darse, aca les dejo mi código y la simulacion, espero haya logrado ser claro y puedan ayudarme, un saludo y muchas gracias, adios!
ahh se me olivdaba uso un 16f88 y lenguaje CCS 4.032
#include <16f88.h>
#fuses intrc,NOWDT,NOLVP,PUT,NOMCLR,NOBROWNOUT
#use delay(internal=4000000)
#use fast_io(a)
#use fast_io(b)
unsigned int CONST LED [10]={0x3f,0x06,0x9B,0x8f,0xa6,0xAd,0xbd,0x27,0xbf,0xaf}; //datos para los displays
int i=0,pin,count=0,total[5],caso=0;
int16 rpm=0,div,rps,mps;
#INT_TIMER0
void tmr0_handler()
{
count++;
if(count==125) // cuento 125 interrupciones 1u*125*32*250=1s
{
rps=GET_TIMER1(); // capturo el valor de tmr1 cuando llegue al segundo el tmr0
rpm=rps/60; // convierto rps a rpm
count=0; // reestablesco contador de interrupciones para tmr0
set_timer1(0); // restablezco tmr1
}
set_timer0(5); // si no ha llegado al segundo otravez inicia tmr0 en 5
}
/*#INT_TIMER1
void tmr1_handler()
{
rpm=0;
set_timer1(0);
}*/
void array(int16 resultado) // función para convertir un entero a array
{
div=10000; // inicialización divisor
for(i=0;i<5;i++) // bucle de conversión
{
total[i]=resultado/div; // se obtiene el primer digito para el array
if(total[i]!=0) // si es igual a cero no se lo considera
resultado=resultado-total[i]*div; // se actualiza el valor de resultado, sin contar el dígito extraido
div=div/10; // se reduce el orden de magnitud del divisor
}
}
void mux() // función de multiplexación
{
pin=40; // inicilaiza el valor del pin en el que comenzará la multiplexación, PIN_A0=40
for(i=0;i<5;i++) // bucle de trabajo
{
output_b(LED[total[i]]); // se despliega dato correspondiente a la variable array a mostrar
output_low(pin); // displays de cátado común, se activa cátodo correspondiente
delay_us(100); // retardo para observación contínua
output_high(pin); // apagamos display, para pasar al siguiente
pin++; // cambiamos de pin
}
}
void main()
{
setup_oscillator(OSC_4MHZ|OSC_INTRC); // fijo oscilador interno
SET_TIMER0(5); // valor de inicio del TMR0
SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_32); // reloj interno y prescaler=32 pra tmr0
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); // reloj externo y preescaler=1 para tmr1
SET_TIMER1(0); // valor de inicio para tmr1
SETUP_ADC(adc_off); // apago el adc
SETUP_ADC_PORTS(NO_ANALOGS); // todas digitales en portA
enable_interrupts(INT_TIMER0); // habilito interrupción por desborde de tmr0
//enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL); // habilito interrupciones
set_tris_a(0xe0); // salidas RA0 a RA4
set_tris_b(0x40); // todas salidas portB, excepto RB6(T1CKI)
output_a(0x1f); // todos los displays apagados
for(i=0;i<5;i++) // inicialización de total
total[i]=0;
while(true) // bucle de trabajo
{
array(rpm); // convierto el valor de rpm a array apra visualizar en displays
mux(); // multiplexo para ver en todos los displays
}
}
la simulacion la adjunto aquí:
tacometro.zip