TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: hekor en 05 de Marzo de 2009, 16:20:31

Título: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: hekor en 05 de Marzo de 2009, 16:20:31
Hola a todos! Les cuento mi problema, tengo un PIC 16f877 con un cristal de 20Mhz; lo que quiero es medir la frecuencia de una señal cuadrada que le entra al pic por el PIN_B4 ,para ello utilizo una interrupcion INT_RB que me cuenta los flancos de subida; a su vez con el timer0 muestro en la pantalla el numero de flancos de subida que han habido en 1 segundo (frecuencia). Bueno hasta aqui todo bien, para frecuencias entre 0Hz y aproximadamente 17Khz me las mide "correctamente" (con errores pero que no me importan mucho), a partir de los 17khz ya se vuelve loco.

Les adjunto el codigo:
Código: [Seleccionar]
#include <16f877.h>



#use delay(clock=20000000)

#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT





#include "lcd.c"





int flancos[6];

int frec[6];

int aux=0;

int x=0;

int estado=0;

int estado_temp=0;





void mostrar(int dato[]){

int aux1=5;

int num_izq=0;

lcd_putc("Frec: ");

while (aux1!=-1) {

if ( (dato[aux1]!=0) || (num_izq==1) ){

      printf(lcd_putc,"%d",dato[aux1]);

num_izq=1;

}

else lcd_putc(" ");

aux1--;

}

lcd_putc(" Hz");

}





#int_rb

void rutina_rb(){

int aux2=0;

estado=input(PIN_B4);

if (estado!=estado_temp) {

if (estado_temp==0 && estado==1) {

flancos[0]++;

for (aux2=0;aux2<=5;aux2++) {

if (flancos[aux2]==10) {

flancos[aux2+1]++;

flancos[aux2]=0;

}

}

}

}

estado_temp=estado;

}





#int_TIMER0



void rutina_timer0() {

int aux3=0;

   x++;

   if (x==76) { //x==76 1seg

x=0;

for (aux3=0;aux3<=5;aux3++) {

frec[aux3]=flancos[aux3];

}

for (aux3=0;aux3<=5;aux3++) {

flancos[aux3]=0;

}

}

   SET_TIMER0(0);

}





void main() {

for (aux=0;aux<=5;aux++) flancos[aux]=0;

lcd_init();

set_tris_b(0b00010000);

SETUP_counters( RTCC_INTERNAL, RTCC_DIV_256);

ENABLE_INTERRUPTS(INT_RTCC);

SET_TIMER0(0);



enable_interrupts(int_rb);

enable_interrupts(GLOBAL);

do{

lcd_gotoxy(1,1);

lcd_putc("Calculando...");

lcd_gotoxy(1,2);

mostrar(frec);

}while(1);

}

¿seria posible medir hasta el orden de megaherzios mediante este sistema?  ¿o tendria que realizarlo mediente otros metodos?

Gracias.
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: vtasco en 05 de Marzo de 2009, 18:06:13
probablemente estés llegando al límite del pic a esa frecuencia.
Podrías intentar dividiendo la frecuencia de entrada (con flip flops),tendrás que ver si el error de medición sigue siendo aceptable.

En este link algo de información : http://www.play-hookey.com/digital/frequency_dividers.html

saludos!
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: pablomanieri en 05 de Marzo de 2009, 19:24:37
El problema se puede deber a los retardos que impone la librería del lcd, pues cuando entra a la interrupción y si justo está en algún retardo del lcd puede que haga cualquier cosa. Prueba contando por un segundo sin actualizar el lcd, luego cuando la cuenta termina deshabilita la interrupción, presentas los datos en el lcd y cuando terminas de presentar los datos, comenzás nuevamente a contar habilitando la interrupción. Luego de esto si quieres medir frecuencias mayores debes usar divisores de frecuencia como te lo indicó vtasco
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: hekor en 05 de Marzo de 2009, 19:41:31
Ok muchas gracias por vuestras respuestas, intentare hacer lo que me ha dicho pablomanieri, aislaré todo lo que pueda el conteo de los demas procesos como pueden ser mostrar por el lcd, etc. Si no funcionase recurriria a la solucion de vtasco. ;-)

Ahora me surge otra duda, dentro de la rutina de interrupcion_rb tengo un bucle for que me sirve para ir contando los flancos de subida, ej: cuando llega a 10 flancos aumenta en 1 lo que serian las decenas y asi sucesivamente. La pregunta es ¿este bucle for podria estar causando algun retraso que me afecte a la medicion a altas frecuencias? Mi idea seria quitar este bucle y hacer que la variable que cuenta los flancos pudiese llegar hasta los megas, es decir, una especie de entero de 32bits ¿seria posible hacer eso?
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: cerebro en 05 de Marzo de 2009, 19:56:49
mas que la rutina for, me da la sensacion que son muchos condicionales y estan retrasando el proceso  :? ....
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 05 de Marzo de 2009, 20:52:36
mira esta web...

a lo mejor esto te viene de lujo...
aqui (http://picmania.garcia-cuervo.com/Tecnicas_en_C_0_Indice.php)
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: RedPic en 05 de Marzo de 2009, 22:22:29
mira esta web...

a lo mejor esto te viene de lujo...
aqui (http://picmania.garcia-cuervo.com/Tecnicas_en_C_0_Indice.php)

La que muestras es la versión de PicManía (http://picmania.garcia-cuervo.com) pero todo lo tienes aquí mismo en el Foro:

Serie Técnicas en C : Presentación e Indice de Contenidos (http://www.todopic.com.ar/foros/index.php?topic=14427.0)

Midiendo un pulso. 1ª Parte. Tiempo en Alto con INTEXT (http://www.todopic.com.ar/foros/index.php?topic=14428.0)
Midiendo un pulso. 2ª Parte. Tiempo en Alto con INTCCP (http://www.todopic.com.ar/foros/index.php?topic=14479.0)
Midiendo un pulso. 3ª Parte. Tiempo en Alto con INTRB (http://www.todopic.com.ar/foros/index.php?topic=14528.0)
Midiendo un pulso. 4ª Parte. El pulso completo. El Periodo y la Frecuencia (http://www.todopic.com.ar/foros/index.php?topic=14434.0)
Generando un pulso. 1ª Parte. Onda simétrica con INTRTCC (http://www.todopic.com.ar/foros/index.php?topic=14531.0)
Generando un pulso. 2ª Parte. Onda Simétrica Mediante INTCCP en modo Compare (http://www.todopic.com.ar/foros/index.php?topic=14590.0)
Múltiples lapsus largos de tiempo con una sola interrupción (http://www.todopic.com.ar/foros/index.php?topic=24801.0)
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: hekor en 06 de Marzo de 2009, 11:21:32
He utilizado la tecnica de medir el tiempo en alto mediante int_ext y a partir de 30Khz no mide bien ... :S nose si alguien habra conseguido medir frecuencias mayores mediante ese metodo.

El profesor me ha dicho que el consiguio medir frecuencias de hasta 100Khz programando el mismo pic (16f877) con BASIC y una instruccion llamada PULSIN. Pero el problema es que yo lo quiero en CCS...
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: MLO__ en 06 de Marzo de 2009, 12:05:15
Hola.

Pues los amigos del CCS tienen un frecuencimetro que va muy bien, revisa el EX_FREQC.c que esta en la carpeta de ejemplos.

Saludos
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 06 de Marzo de 2009, 21:22:31
mira esta web...

a lo mejor esto te viene de lujo...
aqui (http://picmania.garcia-cuervo.com/Tecnicas_en_C_0_Indice.php)

La que muestras es la versión de PicManía (http://picmania.garcia-cuervo.com) pero todo lo tienes aquí mismo en el Foro:

Serie Técnicas en C : Presentación e Indice de Contenidos (http://www.todopic.com.ar/foros/index.php?topic=14427.0)

Midiendo un pulso. 1ª Parte. Tiempo en Alto con INTEXT (http://www.todopic.com.ar/foros/index.php?topic=14428.0)
Midiendo un pulso. 2ª Parte. Tiempo en Alto con INTCCP (http://www.todopic.com.ar/foros/index.php?topic=14479.0)
Midiendo un pulso. 3ª Parte. Tiempo en Alto con INTRB (http://www.todopic.com.ar/foros/index.php?topic=14528.0)
Midiendo un pulso. 4ª Parte. El pulso completo. El Periodo y la Frecuencia (http://www.todopic.com.ar/foros/index.php?topic=14434.0)
Generando un pulso. 1ª Parte. Onda simétrica con INTRTCC (http://www.todopic.com.ar/foros/index.php?topic=14531.0)
Generando un pulso. 2ª Parte. Onda Simétrica Mediante INTCCP en modo Compare (http://www.todopic.com.ar/foros/index.php?topic=14590.0)
Múltiples lapsus largos de tiempo con una sola interrupción (http://www.todopic.com.ar/foros/index.php?topic=24801.0)



cierto... lo que pasa es que la de picmania la tenia en favoritos, y la del foro no lo recordaba bien donde estaba... por eso puse ese link....
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 06 de Marzo de 2009, 21:36:25
He utilizado la tecnica de medir el tiempo en alto mediante int_ext y a partir de 30Khz no mide bien ... :S nose si alguien habra conseguido medir frecuencias mayores mediante ese metodo.

El profesor me ha dicho que el consiguio medir frecuencias de hasta 100Khz programando el mismo pic (16f877) con BASIC y una instruccion llamada PULSIN. Pero el problema es que yo lo quiero en CCS...

yo lo hice.... solo que no llegaba a 82khz.....
use la interrupcion de la patilla rb0 , y la interrupcion timer0
el primero(int_ext) lo unico que hacia era sumar los pulsos
y el segundo(int_rtcc) hice unas lineas de programa que me generaban un tiempo de aproximadamente un segundo, pasado este segundo guardaba el valor en una variable
y reseteaba el contador de pulsos

#int_ext
void entrada()
{
   ++pulso;
}

#int_rtcc
void time()
{
   ++tiempo;
   if(tiempo>19250){
      tiempo = 0;
      seg = pulso/2;
      pulsos= pulso*30;
      j=pulsos/10000 %10;
      jj=pulsos/1000 %10;
      jjj=pulsos/100 %10;
      jjjj=pulsos/10 %10;
      jjjjj=pulsos   %10;
      pulso = 0;
   }
}

mas o menos asi....
decir que utilice un pic 16f628a... el 16f877 aun no lo he utilizado pero imagino que sera lo mismo
mismo perro con diferente collar

Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: hekor en 09 de Marzo de 2009, 08:40:57
Con el ejemplo de EX_FREQ.C consegui llegar a 60Khz :S

Me gustaria saber si alguien ha llegado a medir 100Khz y mediante que metodo, no tiene porque ser mediante el puerto rb :S
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: MLO__ en 10 de Marzo de 2009, 03:12:09
Hola.

Yo medi con el ejemplo de los de CCS hasta mas de 3.5MHz sin problema (no necesitaba subir mas la frecuencia)
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 10 de Marzo de 2009, 20:01:26
que ejemplo era?
si puedes indicarnoslo.... mejor que mejor, asi tod@s aprenderemos algo nuevo..... nunca es tarde si la dicha es buena jejejee

que era de la web oficial del ccs?
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: MLO__ en 11 de Marzo de 2009, 00:32:31
Pues los amigos del CCS tienen un frecuencimetro que va muy bien, revisa el EX_FREQC.c que esta en la carpeta de ejemplos.
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 14 de Marzo de 2009, 15:29:55
como haces funcionar el ejemplo? a mi no me acaba de funcionar muy bien,,,,
el 16f877 tiene el contador t1cki, es un contador de 32bits?
yo uso el 16f628 y con este he llegado a 79khz con la interrupcion INT_EXT
deja algun tipo de flang esta interrupcion en algun registro¿
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ElVale en 15 de Marzo de 2009, 02:29:31
Ese ejemplo EX_FREQC.C lo veo bien raro, no se ni por donde entra a señal.

Si yo quisiera hacer un frecuencímetro haría lo siguiente:

1. Habilito interrupción externa para que detecte la señal cuadrada entrante.
2. Al llegar la interrupción externa pondría el timer1 en 0 y lo pondría a correr, además habilito la interrupción de overflow del timer1
3. Al llegar un overflow del timer1 lo sumaría a un contador (overflows++)
4. Al llegar una nueva interrupción externa (un nuevo período de la señal cuadrada entrante) multiplico el numero de overflows que se llevan hasta ahora por 65536 (timer1 es de 16bits) y a eso le sumaría lo que lleva timer1 hasta ahora (get_timer1()).
5. A este resultado que sería aproximadamente el número de ciclos que se lleva un periodo de la señal cuadrada entrante lo multiplicaría por el periodo de un ciclo de reloj, es decir por 4/Fosc. Hasta aqui tengo el período de la señal cuadrada. Para hallar la frecuencia no es sino sacar el inverso de esto y listo. Es decir
FrecuenciaSeñalCuadrada = inverso(ciclos*4/Fosc)=Fosc/(4*ciclos).
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 15 de Marzo de 2009, 11:51:08

2. Al llegar la interrupción externa pondría el timer1 en 0 y lo pondría a correr, además habilito la interrupción de overflow del timer1
3. Al llegar un overflow del timer1 lo sumaría a un contador (overflows++)
4. Al llegar una nueva interrupción externa (un nuevo período de la señal cuadrada entrante) multiplico el numero de overflows que se llevan hasta ahora por 65536 (timer1 es de 16bits) y a eso le sumaría lo que lleva timer1 hasta ahora (get_timer1()).


yo hace poco que estoy con el c....
me podrias explicar mejor eso del overflows? que es?

es un tipo de interrupcion como anteriormente dices, pero....? yo tengo un manual del ccs y no pone nada del overflow tansolo lo referente a PSP_OVERFLOW()
podrias explicarme eso de que va?
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: MLO__ en 16 de Marzo de 2009, 00:05:57
Hola.

La señal entra por el pin RC0.
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: Suky en 16 de Marzo de 2009, 00:52:42
Citar
me podrias explicar mejor eso del overflows? que es?

Overflow: Cuando el contador del timer1 pasa de 0xFFFF (65535) a 0x0000. Ocurre un desbordamiento y el contador de reinicia. Al momento del reinicio se activa la bandera TMR1IF (PIR1<0>) poniéndose en 1. Esta activación puede usarse de dos maneras:
•   Para solicitar una interrupción
•   Para ser consultada por poleo
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ElVale en 16 de Marzo de 2009, 01:35:16
La señal entra por el pin RC0.

Si pero en que parte del programa se hace lectura de ese pin?
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: Suky en 16 de Marzo de 2009, 01:38:51
Está configurado para detectar pulsos externos, ósea timer1 en modo contador:
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 16 de Marzo de 2009, 04:37:29
Citar
me podrias explicar mejor eso del overflows? que es?

Overflow: Cuando el contador del timer1 pasa de 0xFFFF (65535) a 0x0000. Ocurre un desbordamiento y el contador de reinicia. Al momento del reinicio se activa la bandera TMR1IF (PIR1<0>) poniéndose en 1. Esta activación puede usarse de dos maneras:
•   Para solicitar una interrupción
•   Para ser consultada por poleo


Muchas gracias Suky por aclararmelo.... ahora me ha quedado claro....
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: MLO__ en 16 de Marzo de 2009, 09:39:16
El programa esta muy bien comentado en lo que hace .... es solo cuestion de leer  :?
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 17 de Marzo de 2009, 19:43:59
cierto en los comentarios lo explica bien.... pero yo no comprendo la lectura es erronea.... lo probe con el proteus y me daba valores nada correctos....
no se...
yo al final con el 16f628a he conseguido llegar a 290khz
aqui va mi programa....

Citar
#include <16F628a.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)    //one instruction=0.2us
#use fast_io (a)
#include <lcd_portb.c>
#byte porta = 0x06
#byte cmcon = 0x1f

unsigned int ajuste = 0;
unsigned int j,jj,jjj,jjjj,jjjjj = 0;
unsigned long pulsos,pulsos2 = 0;
unsigned long tiempo = 0;

#int_timer0
void time()
{
   ++tiempo;
   if(tiempo>76){                                                //la condicion se cumple cada 0.9998 segundos
         j = pulsos2;                                          //
         jj = pulsos/1000 %10;                                    //prepara valores de las variables
         jjj = pulsos/100 %10;                                    //para mostarlos en el lcd
         jjjj = pulsos/10 %10;                                    //
         jjjjj = pulsos %10;                                       //
         lcd_gotoxy(1,1);
         if(pulsos2<=0){
            printf(lcd_putc, "Freq= %lu Hz  "pulsos);
            ajuste = 181;                                       //ajustes de la interrupcion del timer0 para frequencias inferiores a 10Khz
         }
         else
         {
            if(pulsos2<=4){
               printf(lcd_putc, "Freq= %u%u,%u Khz  "j,jj,jjj);
               ajuste = 168;                                    //ajustes de la interrupcion del timer0 para frequencias inferiores a 40Hkz
            }
            else
            {
                  if(pulsos2<=26){
                  printf(lcd_putc, "Freq= %u%u,%u Khz  "j,jj,jjj);
                  ajuste = 154;                                 //ajustes de la interrupcion del timer0 para frequencias inferiores a 250Hkz
               }
               else
               {
                  printf(lcd_putc, "Freq= %u%u,%u Khz  "j,jj,jjj);
                  ajuste = 127;                                 //ajustes de la interrupcion del timer0 para frequencias superiores a 250Hkz
               }
            }
                                       
         }
         set_rtcc(ajuste);                                       //asigna el valor "ajuste" para ajustar el valor de frecuencias a diferentes valores
         pulsos = tiempo = pulsos2 = 0;                              //setea valores
   }
}   


void main()
{
   cmcon = 0x07;                                                //comparadores en off
   set_tris_a (0x01);                                             //solo esta el PIN_A0 como entrada, el resto salidas
   enable_interrupts(int_timer0);                                    //habilito interrupciones timer0
   setup_timer_0(rtcc_internal | rtcc_div_256);                        //configuro interrupciones timer0
   enable_interrupts(global);                                       //activo las interrupciones habilitadas
   
      lcd_init();                                                //inicio el LCD
      while(true){                                             //bucle infinito
         do{
            while(input(PIN_A0)){
               ++pulsos;
               while(input(PIN_A0)){}
            }
         }while(pulsos != 10000);                                 //hasta que pulsos no sea 10000, repetira el bucle
         pulsos = 0;                                             //setea pulsos
         ++pulsos2;                                             //suma 1 a pulsos2, con este valor obtendremos las decenas de millar,centenasde millar y unidades de millon
         
      }


}
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: MLO__ en 18 de Marzo de 2009, 00:12:56
Hola.

Monta el circuito, no te preocupes, funciona muy bien. En el proteus no simula muy bien que digamos -a mi no me corrio bien- pero en fisico si que funciona.
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 18 de Marzo de 2009, 05:41:58
en proteus si no tienes un buen ordenador...
al tener que contar uno a uno los inpulsos se demora de mucho tiempo, ademas hasta que se estabiliza pasan un par de segundos cosa que en una proboard no pasa... MLO__ tu crees que demora mas ciclos utiles estas lineas....

Citar
      while(true){                                             //bucle infinito
         do{
            while(input(PIN_A0)){
               ++pulsos;
               while(input(PIN_A0)){}
            }
         }while(pulsos != 10000);                                 //hasta que pulsos no sea 10000, repetira el bucle
         pulsos = 0;                                             //setea pulsos
         ++pulsos2;                                             //suma 1 a pulsos2, con este valor obtendremos las decenas de millar,centenasde millar y unidades de millon
         
      }

o estas?

Citar
      while(true){                                             //bucle infinito
         do{
            while(input(PIN_A0)){
               ++pulsos;
                if(pulsos==10000){
                     pulsos = 0;
                     ++pulsos2;
               while(input(PIN_A0)){}         
      }
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: MLO__ en 19 de Marzo de 2009, 03:08:05
Hola.

en proteus si no tienes un buen ordenador...

La simulacion solo ocupa el 15% del procesador .... es mas bien problemas del proteus -el tiene sus fallas-  :mrgreen:

Para verificar lo que quieres, revisa el archivo LIST generado por el compilador y compara cual es el mas eficiente.

Saludos
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 19 de Marzo de 2009, 06:37:06
anda.... como decia mi abuela.... nunca te iras a la cama sin saber algo nuevo....
no sabia ese pequeño ""truquillo""
gracias MLO__ todo buenos consejos si señor....
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: cerebro en 21 de Marzo de 2009, 18:03:41
 :) hola gente estube probando el programa en proteus y hasta los 10 Mhz andubo perfecto con un 16f877a (simulado en proteus), modificaron el cristal correctamente?.
Ahora tengo una consulta, segun parece a la funcion la podemos aplicarlo a cualquier otro pic como un 18f4550 no?. bueno cuando hago eso, osea cambio el header y modifico el clock y descomento una linea en el programa ya no me funciona el frecuencimetro  :( . Alguien ha utilizado esta rutina en uno de la flia 18f. No pongo el codigo porque es el mismo que el ejemplo.
 Saludos.
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 21 de Marzo de 2009, 21:24:00
teoricamente deberia de funcionar.... yo no he probado pese a que tengo un 18f4550 aqui parado....
algun dia que no tenga faenilla voy a probar todos los ejemplos del ccs, ya que hay buenos programas para trastear un rato....
que hablas del ejemplo del ccs?
yo cree un programa para mis necesidades que no eran muchas..... un cuentarevoluciones..... pero probe a ver la frequencia maxima que podria coseguir con el circuito y el 16f628a....
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: cerebro en 21 de Marzo de 2009, 21:35:19
 :mrgreen: si es el ejemplo frecq del CCS.... lo voy a tener que agarrar de nuevo con mas calma.... y de ultima tratar de copiar la idea  :)
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: MLO__ en 22 de Marzo de 2009, 01:38:15
Hola cerebro.

A mi me funciono muy bien con un 18F452 ... lo que no pude probarlo fue con un PIC12 ... no supe como pu**s conectarlo  :D

Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: DT85 en 19 de Octubre de 2009, 06:44:22
cierto en los comentarios lo explica bien.... pero yo no comprendo la lectura es erronea.... lo probe con el proteus y me daba valores nada correctos....
no se...
yo al final con el 16f628a he conseguido llegar a 290khz
aqui va mi programa....

Citar
#include <16F628a.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)    //one instruction=0.2us
#use fast_io (a)
#include <lcd_portb.c>
#byte porta = 0x06
#byte cmcon = 0x1f

unsigned int ajuste = 0;
unsigned int j,jj,jjj,jjjj,jjjjj = 0;
unsigned long pulsos,pulsos2 = 0;
unsigned long tiempo = 0;

#int_timer0
void time()
{
   ++tiempo;
   if(tiempo>76){                                                //la condicion se cumple cada 0.9998 segundos
         j = pulsos2;                                          //
         jj = pulsos/1000 %10;                                    //prepara valores de las variables
         jjj = pulsos/100 %10;                                    //para mostarlos en el lcd
         jjjj = pulsos/10 %10;                                    //
         jjjjj = pulsos %10;                                       //
         lcd_gotoxy(1,1);
         if(pulsos2<=0){
            printf(lcd_putc, "Freq= %lu Hz  "pulsos);
            ajuste = 181;                                       //ajustes de la interrupcion del timer0 para frequencias inferiores a 10Khz
         }
         else
         {
            if(pulsos2<=4){
               printf(lcd_putc, "Freq= %u%u,%u Khz  "j,jj,jjj);
               ajuste = 168;                                    //ajustes de la interrupcion del timer0 para frequencias inferiores a 40Hkz
            }
            else
            {
                  if(pulsos2<=26){
                  printf(lcd_putc, "Freq= %u%u,%u Khz  "j,jj,jjj);
                  ajuste = 154;                                 //ajustes de la interrupcion del timer0 para frequencias inferiores a 250Hkz
               }
               else
               {
                  printf(lcd_putc, "Freq= %u%u,%u Khz  "j,jj,jjj);
                  ajuste = 127;                                 //ajustes de la interrupcion del timer0 para frequencias superiores a 250Hkz
               }
            }
                                       
         }
         set_rtcc(ajuste);                                       //asigna el valor "ajuste" para ajustar el valor de frecuencias a diferentes valores
         pulsos = tiempo = pulsos2 = 0;                              //setea valores
   }
}   


void main()
{
   cmcon = 0x07;                                                //comparadores en off
   set_tris_a (0x01);                                             //solo esta el PIN_A0 como entrada, el resto salidas
   enable_interrupts(int_timer0);                                    //habilito interrupciones timer0
   setup_timer_0(rtcc_internal | rtcc_div_256);                        //configuro interrupciones timer0
   enable_interrupts(global);                                       //activo las interrupciones habilitadas
   
      lcd_init();                                                //inicio el LCD
      while(true){                                             //bucle infinito
         do{
            while(input(PIN_A0)){
               ++pulsos;
               while(input(PIN_A0)){}
            }
         }while(pulsos != 10000);                                 //hasta que pulsos no sea 10000, repetira el bucle
         pulsos = 0;                                             //setea pulsos
         ++pulsos2;                                             //suma 1 a pulsos2, con este valor obtendremos las decenas de millar,centenasde millar y unidades de millon
         
      }


}

Hola a todos, soy nuevo en este mundillo. He armado el programa en un pic 16f876, y va de maravilla. Pero tengo dudas, el porque el ajuste se hace a esos valores. Es que utilizo las formulas para hallar esos valores (ya que quiero encontrar el equivalente para un circuito con reloj de 4MHz) de la carga del timer, y no me da igual. Lo que quiero entender es el programa!
Otra pregunta: porque le das redundancia a la siguiente instrucción

while(input(PIN_A0)){
               ++pulsos;
               while(input(PIN_A0)){}


La señal se podia introducir por cualquier otro pin?

Gracias de antemano!
Título: Re: Medir frecuencia señal cuadrada mediante INT_RB
Publicado por: ppyote en 20 de Octubre de 2009, 05:27:07
puedes utilizar el pin que tu consideres oportuno... En cuanto a lo de los ajustes es por el retardo que sufre el pic por la escritura en el lcd, a frecuencias muy altas la escritura en el lcd se combierte en una tarea para el pic que demora mucho tienpo, de ahi viene ese valor