Autor Tema: incremento variable durante 1seg  (Leído 3150 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
incremento variable durante 1seg
« en: 13 de Noviembre de 2008, 18:16:08 »
Hola a todos como están, les molesto esta ves por la siguiente duda que me a ocurrido.
Quiero hacer que una variable x me incremente por medio de un 1 en una de las entradas del micro, ósea me explico un poco mas claro suponiendo que tengo un pulsador en el pin A0 y quiero contar cuantas beses fue pulsado este botón durante 1 segundo. tengo claro como se puede hacer eso de declarar las entradas recibir el 1 y too eso pero lo que no se es que como puedo hacer que cuente x beses en 1 segundo.
ojalas me pudiesen echar una manito en esto ya que es para un proyecto que estoy asiendo para la U y lo tengo que entregar en 1 semana +.
bueno saludos que esten bien y espero que me puedan ayudar d(^^)b
 

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: incremento variable durante 1seg
« Respuesta #1 en: 13 de Noviembre de 2008, 18:49:07 »
Podes hacer 2 cosas, en ambos casos usando la interrupcion del timer.
1) Configurar el timer en modo contador, entonces en tu programa principal habilitas la interrupcion, haces un delay_ms(1000); y la deshabilitas.
2) Configuras el timer para que cuente ciclos internos, sacas toda la cuenta para q desborde cada un milisegundo, y con un contador contas hasta 1000. Entonces en tu programa principal haces un while q cuente pulsos de una patita, y q deje de contar cuando el timer haya interrumpido por 1000º vez.
Hay miles de formas, tenes q ver cual es la mas eficaz. Saludos!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: incremento variable durante 1seg
« Respuesta #2 en: 13 de Noviembre de 2008, 18:55:48 »
hola gera grax por la sugerencia pero mi problema es que no se trabajar con los timer :( e visto varios ejemplo pero no los entiendo por eso tengo ploblemas en la programacion es mi gran devilidad como la criptonita de superman jijijij bueno y eso pero a ver si sigo leyendo y entiendo un poco mas de los timer o si me pudiesen explicar con porotitos como funcionan se los agradeceria montones. bueno saludos

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: incremento variable durante 1seg
« Respuesta #3 en: 13 de Noviembre de 2008, 18:59:39 »
Entonces te veo muy mal, porq como sabras los pics son monoprocesador, por lo tanto no hay forma que lleves la cuenta del tiempo y de los pulsos a la vez. No te queda otra q usar alguna clase de interrupcion.
Busca por el foro, hay miles de ejemplos, cronometros, frecuencimetros. Este ultimo es algo muy parecido a lo q necesitas, ya q queres contar la cantidad de pulsos durante un periodo dado.
suerte!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: incremento variable durante 1seg
« Respuesta #4 en: 13 de Noviembre de 2008, 19:10:10 »
Encontre un frecuencimetro q hice hace mucho con la ayuda del modulo CCP del pic16f873.
Lo q se me ocurre ahora es q uses la interrupcion de ccp. En tu programa principal habilitas dicha interrupcion, haces un delay_ms(1000); y la deshabilitas. Y dentro de la interrupcion haces un variable++; y listo.
Te dejo mas o menos en borrador lo q te digo

Código: C
  1. #include <16f873a.h>
  2. #FUSES NOWDT,HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
  3. #use delay(clock=20000000)
  4.  
  5. int pulsos;
  6.  
  7. #int_ccp1
  8. void handle_ccp1_int()
  9. {
  10.    pulsos++;
  11. }
  12.  
  13. void main()
  14. {
  15.    setup_ccp1(CCP_CAPTURE_RE);
  16.    disable_interrupts(int_ccp1);
  17.    enable_interrupts(global);
  18.    delay_ms(10); //esperamos a q se estabilice
  19.    pulsos=0;
  20.    
  21.    enable_interrupts(int_ccp1);
  22.    delay_ms(1000);
  23.    disable_interrupts(int_ccp1);
  24.  
  25.    while(TRUE)
  26.    {
  27.       printf("pulsos: %d",pulsos);
  28.    }
  29. }

vas a tener q agregar todo el tema de la interfaz... ya sea rs232 o a una pantalla de lcd, y alguna forma de empezar a cronometrar y todo eso. Saludos

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado El_Guitre

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1046
Re: incremento variable durante 1seg
« Respuesta #5 en: 13 de Noviembre de 2008, 19:34:08 »
Hola japifer, antes que nada supongo que habras usado el buscador y leido las reglas del foro. Para que te podemos ayudar mejor deberías decirnos como mínimo en que lenguaje estas programando, que compilador estas usando, que micro, etc.

Básicamente es como dice gera, configuras el timmer, activas la interrupción e incrementas una variable cada vez que cae un porotito, una vez pasado el tiempo te fijas cuantos porotitos hay en la bolsa, es decir cuanto vale tu variable.

En el foro esta lleno de ejemplos, pero tienes que ayudar a que te ayuden. Saludos y bienvenido!

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: incremento variable durante 1seg
« Respuesta #6 en: 13 de Noviembre de 2008, 21:01:14 »
hola grax por las dos esplicaciones bueno estoy intentando de hacer un programa en el pic 16f876a en lenguaje C de CCS, con un cristal de 20MHz. mi idea es que por conflictos de los video juegos unos companieros y yo estabamos "peliando" quien asia mayores convinaciones en un juego y salio el tema de que quien era capas de apretar mas rapido una tecla por segundo para ver quien era mejor jijiji en fin y junto que tenia que hacer un proyecto cualquiera para un taller de electronica desidi hacer lo que ya mensione que por lo que dijo gera era un frecuenciometro.
en este en todo este rato e leido hacerca de los timer y voy entendiendo un poco mejor el asunto ahora bien les queria pedir si alguien me hace un programita muy pero muy sensillo para ver como funsiona el timer, ya estoy comprendiendo que hay que hacerlo mediante interrupciones y tambien que se tienen que activar si alguien se apiade de mi y me explica con la activacion del timer y esas cosas asi bueno antemanos grax por la ayuda otorgada por el momento se le agradese la colaboracion ATTE japifer.

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: incremento variable durante 1seg
« Respuesta #7 en: 14 de Noviembre de 2008, 15:32:15 »
hola de nuevo como me dijeron estuve investigado sobre los timer bastante y encontré un tutoría donde explica muy detalladamente como funciona ahora bien hice un programa o mejor dicho frecuencímetro pero  ahora estoy teniendo problemas en capturar el dato de entrada en Hz, por que el programa me esta contando nomás los pulsos de entrada pero no puedo hacer que..... o mejor dicho no se me ocurre como hacer que la entrada cuente una frec determinada ??como tomo los valores en 1 segundo y nada mas ??? hice el timer para que se desbordara en 1 seg (eso creo yo  :)) y intente poner a cero esta variable de cuenta pero tampoco funca bueno les dejo el programa para que vean en que me equivoque y ojalas que me pudiesen echar una manito que de verdad la necesito, bueno de antemano gracias.

#include <16f876a.h>            //pic a utilizar         
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //ordenes para el programador
#use delay (clock=4000000)         //Fosc=4Mhz
#use standard_io(B)
#define use_portb_lcd TRUE         //definir portb lcd
#include<lcd.c>                  //libreria manejo lcd
char flag=0,var=20;   //variables globales
float i=0;
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER0
void interrupcion()
{
   if(flag>var){      //¿ya es 1 segundo?
      var--;         //SI -> decremento var...
      if(var<18)
         var=20;      //...ajuste fino de 1s
      flag=0;//reset flag para contar 1s
       }
       
   set_timer0(61);      //reset TMR0
   flag++;            //incremento variable flag
}

///PROGRAMA
void main(void)

   lcd_init();         //inicializa lcd
   set_tris_b(0x00);                     //portb como salida
   enable_interrupts(INT_TIMER0);            //interrupcion TIMER0 activada
   setup_counters(RTCC_INTERNAL,RTCC_DIV_256);   //configuracion interrupcion TMR0
   set_timer0(61);                        //carga TMR0
   enable_interrupts(GLOBAL);               //activadas interrupciones
   do{                        //bucle...
    if(!input(PIN_A0)){
   printf(lcd_putc,"\njapifer_22.");   //auto publicidad en la 2ºfila lcd
   lcd_gotoxy(2,1);                  //vuelve 1ºfila lcd y apunta la mitad de la columna     
         printf(lcd_putc,"F:%fHz",i);   //muestra por pantalla el numero
         printf(lcd_putc,"\b"); //retrasa el cursor una posicion(escribe encima)
           i=i+1;
           }
       
            }while(TRUE);            //...infinito         
}   
           

Desconectado sander

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 624
Re: incremento variable durante 1seg
« Respuesta #8 en: 14 de Noviembre de 2008, 21:36:01 »
Hola japifer_22

Un error que veo en tu programa es que no habilitas la interrupcion del TMR0, esto hace que tu temporizacion de 1 segundo no funcione, la linea enable_interrupts(GLOBAL); solo te  da paso libre al uso de interrupciones, despues debes especificar que interrupciones vas a utilizar, para esto pon la linea enable_interrupts(INT_TIMER0); despues de enable_interrupts(GLOBAL);.

Luego para reiniciar el contador de pulsos (i) , debes de hacerlo al final de la temporizacion de 1 seg, es decir .... al final de la rutina de interrupcion

Código: C
  1. ///LLAMADA FUNCION INTERRUPCION
  2. #INT_TIMER0
  3. void interrupcion()
  4. {
  5.    if(flag>var){      //¿ya es 1 segundo?
  6.       var--;         //SI -> decremento var...
  7.       if(var<18)
  8.          var=20;      //...ajuste fino de 1s
  9.       flag=0;//reset flag para contar 1s
  10.        }
  11.        
  12.    set_timer0(61);      //reset TMR0
  13.    flag++;            //incremento variable flag
  14. //*********************************************************
  15.  i = 0;               // para reiniciar el contador de pulsos
  16. //*********************************************************
  17. }


Haciendo las modificaciones que te indico tendras un programa que cuenta pulsos cada segundo, pero que te mostrara los resultados muy rapido, lo mejor seria que controles cuando se empieza a contar los pulsos , para esto podrias poner un pulsador de START, y que solo se comienze a contar cuando se presione este pulsador.

Otra cosa mas, arriba mencionabas que el programa es para ver cuantas veces un jugador presiona un boton en un segundo, bueno no te olvides que los pulsadores tienen un fenomeno mecanico conocido como rebotes de contactos que hara que tengas una medicion erronea ya que te apareceran mas pulsos de los que en realidad estan dando.

Saludos
La electrónica es el arte de manipular señales eléctricas que transportan información
Jan Davidse

Visita mi blog
Visita mi canal de youtube

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: incremento variable durante 1seg
« Respuesta #9 en: 15 de Noviembre de 2008, 01:14:52 »
hola sander grax por la acotacion aver voy a provar lo que dices y te comento como me fue.

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: incremento variable durante 1seg
« Respuesta #10 en: 17 de Noviembre de 2008, 03:02:57 »
hola sander mira me e leido la ayuda del compilador en el que estoy trabajando el CCS C y segun lo que dice el ayuda tengo la configuracion de la activacion del timer bueno pero de todas formas hice lo que me dijiste y no me funciono, el problema ahora esque el programa cuenta solo: te pido porfavor si me pudieras correjir en lo que estoy mal mas arriba deje la simulacion em proteus y tambien el programa que estamos comentando para que veas lo que susede si lo pudieras dejar escrito para yo ver de mejor forma en que estoy mal se que es vastante patudo de mi parte pero me esta quedando poco tiempo para solucionar el problema y no puedo echo de todo y no salgo de la @@@ pana pero en fin o si alguien me pudiece ayudar = se los agradeceria montones.
a y perdon por la demora esque estoy por otro ramo asiendo un trabajo con PLC que me tiene exausto es demasiado largo y too eso de programacion de PLC y winCC pero en fin es arina de otro costal ;)  bueno espero que me puedan echar una manito en mi dolor de caveza con lo que es el timer

Desconectado micronet3

  • PIC18
  • ****
  • Mensajes: 288
Re: incremento variable durante 1seg
« Respuesta #11 en: 17 de Noviembre de 2008, 18:12:00 »
hola japiter puede que esto sea tu solucion, un contador sin el uso del timer0
#include <16f877.h>            //pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT
#use delay (clock=4000000)         //Fosc=4Mhz
#define BOTON PIN_B0
#include <lcd.c>

int16 contador;

void main(){
     set_tris_b(0x00);
    contador=0;
   lcd_init();
      lcd_putc("hola mundo");
       lcd_gotoxy(1,2);         //inicializa lcd
   printf(lcd_putc,"%lu",contador);

while(1)
{
if(input(BOTON))
{
while(input(BOTON)==1){


}
contador++;
 lcd_gotoxy(1,2);         //inicializa lcd
 printf(lcd_putc,"%lu",contador);

}
}
}


te adjunto el programa y la simulacion en proteus

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: incremento variable durante 1seg
« Respuesta #12 en: 18 de Noviembre de 2008, 00:33:56 »
hola micronet3 grax por la sujerencia es algo paresido a lo que estoy haciendo, voy a analisar bn y te comento como me fue



Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: incremento variable durante 1seg
« Respuesta #13 en: 19 de Noviembre de 2008, 10:26:10 »
 hola como les va hoy. bueno les comento que logre hacer una rutina con timer donde cada un segundo pasa x evento, pero ahora bien no me la e podido ingeniar para hacer que cuente por el seg y que mantenga reservado ese dato mientra que cuenta un nuevo valor por 1 seg+ y refresque el segundo anterior.
ahora bien analisando lo que dijo el amigo gera funciona bn con unas minimas modificaciones pero en fin el problema en jeneral lo resolvio el grax XD este frecuencimetro funciona bien asta un orden de los 200 o 300 Hz desde ahy hacia arriba va teniendo problemitas al contar por ejemplo al ingresarle una señal de 1KHz la frecuencia me da una de 1,098KHz, bueno a qui les dejo el codigo modificado para ver si me podreis decir que se le puede cambiar a esto para que cuente mejor, ahora bien mi profesor me dijo que claro como mensionaron ustedes mejor que isiera un frecuencimetro, donde tiene que medir una frecuencia de 30KHz esto sin un circuito divisor conectado directamente por eso les ruego que me echaran una manito en el codigo para mejorarlo un poco mas, bueno a qui va el codigo.     

Código: C#
  1. #include <16f876a.h>
  2.  
  3.       #FUSES NOWDT,HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
  4.    
  5.       #use delay(clock=20000000)
  6.      
  7.       #define use_portb_lcd TRUE         //definir portb lcd
  8.      
  9.       #include<lcd.c>                  //libreria manejo lcd
  10.  
  11.  
  12.       float pulsos,frec;
  13.  
  14.       #int_ccp1
  15.  
  16.       void handle_ccp1_int()
  17.  
  18.       {
  19.  
  20.         pulsos=pulsos+1;
  21.         frec=pulsos-1;
  22.       }
  23.  
  24.       void main()
  25.  
  26.       {
  27.         lcd_init();         //inicializa lcd
  28.  
  29.         setup_ccp1(CCP_CAPTURE_RE);
  30.  
  31.         disable_interrupts(int_ccp1);
  32.  
  33.         enable_interrupts(global);
  34.  
  35.         delay_ms(10); //esperamos a q se estabilice
  36.  
  37.         while(TRUE)
  38.  
  39.          {
  40.        
  41.         pulsos=0;
  42.        
  43.         frec=0;
  44.  
  45.         enable_interrupts(int_ccp1);
  46.  
  47.         delay_ms(1000);
  48.  
  49.         disable_interrupts(int_ccp1);
  50.  
  51.        
  52.  
  53.            printf(lcd_putc,"\njapifer_22.");   //auto publicidad en la 2ºfila lcd
  54.            lcd_gotoxy(2,1);                  //vuelve 1ºfila lcd y apunta la mitad de la columna    
  55.            printf(lcd_putc,"F:%fHz",frec);   //muestra por pantalla el numero
  56.            printf(lcd_putc,"\b"); //retrasa el cursor una posicion(escribe encima)
  57.  
  58.         }
  59.  
  60.       }
  61.  
  62. tambien les dejo el codigo que cuenta cada un seg se los agrego en el rar que les paso con el circuito en CCS C y proteus
  63.  
  64. #include <16f876a.h>            //pic a utilizar        
  65. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP // Opciones de configuración
  66. #use delay(clock=4000000)              // Velocidad del Cristal : 4 Mhz
  67. #define use_portb_lcd TRUE         //definir portb lcd
  68. #define BOTON PIN_A0
  69. #include <lcd.c>                  //libreria manejo lcd
  70.  
  71.  
  72. byte const NInts=30;                   // Numero de interrupciones para 1 Segundo
  73.  
  74. // VARIABLES GLOBALES
  75.  
  76. char C_Ints=0;                         // Contador de Interrupciones ocurridas
  77. char Flag=0;                           // Flag que cambia cada NInts interrupciones
  78. float K,i,a;
  79.  
  80. #int_RTCC                              // Interrupción por desbordamiento
  81. RTCC_isr() {                           // del TIMER0 RTCC
  82.  
  83.   if(C_Ints > NInts){                  // Si las ints ocurridas > ints para 1 Seg.
  84.  
  85.     if(Flag==0){
  86.       Flag=1;
  87.     }
  88.     else{
  89.       Flag=0;
  90.     }
  91.     C_Ints=0;                          // Reinicializo Contador de Ints
  92.   }
  93.   ++C_Ints;                           // Incremento el número de interrupciones  
  94.  }                                      // Ocurridas
  95. void main(void) {
  96.  
  97.   setup_counters(RTCC_INTERNAL,RTCC_DIV_128);// TIMER0: Clock Interno, Presescaler 128
  98.   setup_timer_1(T1_DISABLED);                // para una RTCC cada 33.3 milisegundos
  99.   setup_timer_2(T2_DISABLED,0,1);            // -> 1 Segundo = 30 RTCC
  100.   setup_comparator(NC_NC_NC_NC);
  101.   setup_vref(FALSE);
  102.   enable_interrupts(INT_RTCC);               // Habilito Interrupción RTCC
  103.   enable_interrupts(global);                 // Habilito Interrupciones
  104.   lcd_init();         //inicializa lcd
  105.  
  106.  
  107.   do{ // Bucle infinito
  108.  
  109.     if(Flag==K){}
  110.     else
  111.     {                                        // si ha cambiado Flag ...
  112.  // AQUI HAGO LO QUE DESEE CADA 1 SEGUNDO
  113.                i=i+1;
  114.                a=i-1;
  115.                printf(lcd_putc,"\njapifer_22.");   //auto publicidad en la 2ºfila lcd
  116.                lcd_gotoxy(2,1);                  //vuelve 1ºfila lcd y apunta la mitad de la columna    
  117.                printf(lcd_putc,"F:%fHz",a);   //muestra por pantalla el numero
  118.                printf(lcd_putc,"\b"); //retrasa el cursor una posicion(escribe encima)
  119.            
  120.  
  121.       k=Flag;                                // Guardo estado anterior de Flag
  122.     }
  123.  
  124.   }While(TRUE);
  125. }

bn en este ultimo si alguien tiene una idea de como dejarlo para que tome el valor de frecuencia cada un segundo seria fenomenal ya que no se me ocurre como hacerlo ^^ bueno grax por la ayuda otorgada asta el momento.
« Última modificación: 19 de Noviembre de 2008, 11:05:19 por un Moderador »

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: incremento variable durante 1seg
« Respuesta #14 en: 19 de Noviembre de 2008, 12:27:08 »
Hola! ahi va quedando mejor, te felicito ;)
Pero vos queres hacer algo q mida altas frecuencias? o bajas? Porq segun lo q lei mas arriba es para ver quien de tus amigos presiona mas rapido un boton.
Si queres hacer un frecuencimetro, tenes q tener en cuenta mas o menos q frecuencia vas a medir. Si esta es muy alta, lo q haces es medir una cantidad de pulsos en un periodo dado (como venimos haciendo). Pero si la frecuencia es baja, lo que se hace es medir el periodo entre pulso y pulso. Es dificil hacer un frecuencimetro que funcione bien tanto para altas como para bajas frecuencias.

Ahora, viendo tu codigo, no entiendo por q tenes una variable pulsos y una frecuencia. Si la medicion dura un segundo, pulsos coincide con frecuencia. En fin, te doy una ayudita sobre el otro codigo:

Código: C#
  1. while(TRUE)
  2.  {
  3.     if(Flag==K)
  4.    {
  5.        if( input(PIN_B1) )          //suponiendo q tus pulsos entran por RB1
  6.             pulsos++;
  7.    }
  8.     else
  9.     {                                        // si ha cambiado Flag ...
  10.  // AQUI HAGO LO QUE DESEE CADA 1 SEGUNDO
  11.                //aca podes deshabilitar la interrupcion del timer para q no moleste
  12.                printf(lcd_putc,"\njapifer_22.");   //auto publicidad en la 2&#186;fila lcd
  13.                lcd_gotoxy(2,1);                  //vuelve 1&#186;fila lcd y apunta la mitad de la columna    
  14.                printf(lcd_putc,"%d pulsos en un segundo",pulsos);   //muestra por pantalla el numero
  15.  
  16.                //aca podrias poner un cartelito preguntando si vas a realizar
  17.                //otra medicion, entonces espera a q pulses para realizar la siguiente
  18.                while ( !input(PIN_B1) );
  19.                //aca tendrias q habilitar la interrupcion del timer de nuevo
  20.       k=Flag;                                // Guardo estado anterior de Flag
  21.     }
  22.   }

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein


 

anything