El circuito es realmente sencillo, el cual claramente puede mejorarse ya que no tiene ningún tipo de acondicionamiento de señal, es decir la entrada de interrupción del microcontrolador como sabemos funciona entre 0 y 5V por lo que una buena mejora seria un transistor de RF para adaptar estos niveles de tensión, de todas formas el circuito funciona muy bien, en el vídeo se puede ver como conectando el pin de entrada de medición a la salida del oscilador del micro podemos leer los 20MHz del cristal, el circuito lo he probado con un oscilador a cristal en base a dos compuertas NAND en el cual he probado varios cristales y funciona bien en todos estos.
Link al amplificador para frecuencimetro:
http://electgpl.blogspot.com.ar/2017/03/amplificador-para-frecuencimetro.html
El funcionamiento es relativamente simple, el microcontrolador usa dos timers, el timer1 para medir pulsos externos y el timer0 para resetear cada 1s como base de tiempo.
En este caso tenemos que recurrir al datasheet para analizar los parámetros de propagación electrónica que tiene la entrada de captura externa.
Este es el cuadro donde podemos ver las entradas de captura externa que hacen referencia según su numero adjunto en la cota a la propagación mínima de transición entre 1 y 0 que podemos ver en la siguiente tabla.
En esta tabla podemos ver el valor de T1CKI que se encuentra al rededor de los 20ns, entonces suponiendo el peor de los casos de 20ns de periodo estaríamos hablando de 50MHz, aunque se puede ingresar una frecuencia mayor, caerá un poco la sensibilidad pero podríamos ingresarla sin problemas.
El timer1 lo vamos a configurar como contador de flancos externos de 16bit, es decir de 0 a 65535, pero solamente vamos a utilizar de el (por el momento) el flag overflow, es decir cada vez que el timer1 cuente 65536 pulsos tendremos un 1 en su flag de overflow, entonces contaremos cuantos overflow registramos del timer1, cada overflow registrado corresponde a 65536 pulsos, entonces si registramos por ejemplo 50 overflow, entonces es porque medimos una frecuencia de 3.276MHz, entonces simplemente con contar overflows cosa que puede hacer el microcontroaldor con su bus a 1MHz (Cristal de 4MHz), podríamos saber la frecuencia, pero no seria tan exacta ya que serviria solo para frecuencias altas del orden del MHz, por ello vamos a realizar una union de variables de 16bit en cuanto al valor TMR1H y TMR1L, junto a el valor medido por el Timer0 y realizaremos un valor de 32bit con la función make32. de esta manera podremos medir frecuencias mas altas, pero no sera muy exacto para medir ciclos de trabajo.
La finalidad de este proyecto es la medición de frecuencia de oscilador de un equipo VHF transceptor en la banda de 2m, por lo que solo me interesaba que mida desde los 100MHz a los 500MHz, aquí aparece la otra duda, como lograr esas frecuencias mas elevadas. Bueno en mi caso he comprado un prescaler MC12080 el cual admite una frecuencia máxima de 1,1GHz aunque en el datasheet lo han probado con 1,4GHz, el mismo es divisor entre 10, 20, 40, y 80. Esto quiere decir que si ingreso una frecuencia de 144MHz a la salida del prescaler tendré 1,8MHz (si divido por 80). Por esta razón notaran que en la linea de printf del programa hay una comentada en donde toma el valor leído por el microcontrolador y lo multiplica por 80, de esta forma compensamos la división entre 80 del prescaler.
El programa es muy sencillo y es el siguiente:
- #include <16F883.h>
- #fuses HS,NOWDT,NOPROTECT,PUT,NOLVP,NOMCLR
- #use delay(clock=20000000)
- #bit FlagDesbordaTimer1 = 0x0C.0
- #include <LCD.C>
- void main(){
- lcd_init();
- int Ciclo1byte, Ciclos;
- float Frecuencia;
- long ParteAlta, ParteBaja;
- while(true){
- Ciclo1byte = 0;
- Ciclos = 0;
- ParteAlta = 0;
- FlagDesbordaTimer1 = 0;
- set_timer1(0);
- setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
- while(Ciclos!=0xFF) {
- Ciclo1byte = 0;
- while(Ciclo1byte!=0xFF) {
- if(FlagDesbordaTimer1){
- FlagDesbordaTimer1 = 0;
- ParteAlta++;
- }
- else{
- delay_cycles(5);
- }
- delay_cycles(62);
- Ciclo1byte++;
- }
- delay_cycles(216);
- Ciclos++;
- }
- delay_cycles(211);
- setup_timer_1(T1_DISABLED);
- if(FlagDesbordaTimer1){
- ParteAlta++;
- }
- ParteBaja = get_timer1();
- Frecuencia = make32(ParteAlta,ParteBaja);
- printf(lcd_putc,"Frecuencimetro \n");
- // printf(lcd_putc,"fo= %03.4f MHz\n",(Frecuencia*80)/1000000);
- printf(lcd_putc,"fo= %03.4f MHz\n",Frecuencia/1000000);
- }
- }


