Autor Tema: Ayuda contador de 00 - 99 con boton?  (Leído 2064 veces)

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

Desconectado JP0010

  • PIC10
  • *
  • Mensajes: 3
Ayuda contador de 00 - 99 con boton?
« en: 07 de Junio de 2015, 19:29:23 »
Buenas amigos me presento ante todos, les vengo a pedir ayuda debido que eh buscado y no eh podido dar con el problema..

les digo que estoy iniciado en esto de la programación de los pics y por ahi se me van algunas duda cuando programo en c debido que no se cuales son los funciones que usas los controladores, eh buscado y creo que tengo la solución pero cuando implemento no resulta .. bien en fin la cuestión de mi problema es que empece con un contador sencillo que por cierto lo encontré en esta pagina luego me decidi a ser de mas dígitos pero si quería 3 dígitos ya estaría utilizado todos los puerto de pic16f887a y bueno ahi fue donde me puse a investigar y resulta que con la multiplexacion puedes colocar cuantos quiera y aquí es donde viene mi problema, encontré uno en la web que cuenta automáticamente y yo quiero es que cada vez que pulse el botón me cuente hasta 99 en resumidas cuenta un contador de 00 - 99 con un pic y 2 display 7 segmentos iniciados por pulsadas.

este es el codigo encontrado:
[spoiler]
Código: [Seleccionar]
#INCLUDE <16F887.h>
#USE DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
Byte CONST display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
#BYTE PORTB= 6
#BYTE PORTC= 7
#DEFINE TUNI PORTC,0 //Definición de variables
#DEFINE TDEC PORTC,1 //Definición de variables

INT CONT;   //Declarar la variable CONT como
            //un entero, es decir de 8 bits
LONG CONTRET;  //Declarar la variable CONTRET
               //como long, es decir de 16 bits
               
               
VOID MOSTRAR( ) //Rutina mostrar
{
   INT UNI,DEC;   //Declarar las variables UNI, DEC
                  //como un entero, es decir de 8bits
   DEC=CONT/10;
   UNI=CONT%10;
   PORTB=(DISPLAY[UNI]);   //Muestra lo que hay en unidades
                           //en el display
   BIT_SET (TUNI);         //Enciende el display de unidades
   DELAY_MS(1);            //Retardo de 1 milisegundos
   BIT_CLEAR(TUNI);        //Apaga el display de unidades
   PORTB=(DISPLAY[DEC]);   //Muestra lo que hay en unidades
                           //en el display
   BIT_SET (TDEC);         //Enciende el display de decenas
   DELAY_MS(1);            //Retardo de 1 milisegundos
   BIT_CLEAR(TDEC);        //Apaga el display de decenas
   
}


VOID RET1SEG() //Rutina RET1SEG
{
   CONTRET=500; //Cargue con 500 la variable CONTRET
   WHILE (CONTRET>0) //Mientras que la variable CONTRET sea mayor que cero
   {
      MOSTRAR();        //Llamar la rutina MOSTRAR
      CONTRET--;        // Decremente la variable CONTRET
   }
}

void MAIN()
{
   SET_TRIS_B(0); //El puerto B esta configurado como salida
   SET_TRIS_C(0); // El puerto C esta configurado como salida
   CONT=0;  //la variable CONT se inicializa con cero

   WHILE(TRUE) //Haga por siempre
   {
      CONT=0;
      WHILE(CONT<100) //mientras la variable CONT es menor que 100
      {
         RET1SEG( ); //Llama la rutina RET1SEG
         CONT++; //Incrementa la variable CONT
      }
     
   }
}
[/spoiler]


y este el que modifique guiando del anterior pero tratando que leea mis pulsadas:

[spoiler]
Código: [Seleccionar]
#Include <16F877A.h>               
#Fuses XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP   //Configuracion de fusibles
#Use delay (clock=4000000)  //reloj=4Mhz
#Use fast_io(A)   
#Byte portb=6
#Byte porta=2 
#Byte portc= 7
#Define uno portc,0 //Definición de variables
#Define dos portc,1 //Definición de variables                   


int i=0, j=0;   //displays
void mostrar( )
{
   int display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
   
   digito1=cont%10;
   digito2=cont/10;
   
   portb =(display[i]);
   bit_set (uno); //prendo el primer display
   delay_ms(1);
   bit_clear(uno); //lo apago
   portb=(display[j]);
   bit_set (dos); //perdo el segundo
   delay_ms(1);
   bit_clear(dos);
         
}     
void pulsadores(){                            //Funcion de conteo de eventos
  if(input(pin_A0)){                     //Esta cerrado el pulsador?
    delay_ms(5);                          //Si, elimina rebotes
    cont++;
    if (i>9){                      //hasta que sea 9
      i=0;                         //borra unidades e
      j++;                          //incrementa las decenas
        if(j>9){                    //hasta 9
          j=0;                      //borra las decenas
        }
    }
  }             

while (bit_test(porta,0)==0){           //Espera visualizando datos
  mostrar();                            //mientras la tecla esta presionada
  }
     if(input(pin_A1)){                  //Esta cerrado el pulsador?
        delay_ms(5);                      //Si, elimina rebotes
        i=0; j=0;            //reset
     }
}

void main(){
                         
set_tris_b(0);                         //portb como salida
set_tris_a(255);                         //RA0 y RA1 entradas
disable_interrupts(GLOBAL);               //activadas interrupciones

do{                                       //bucle...
     mostrar();                         
     pulsadores();                           
}while(TRUE);                           
}
[/spoiler]


espero me ayuden,   :-/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Ayuda contador de 00 - 99 con boton?
« Respuesta #1 en: 07 de Junio de 2015, 19:54:22 »
Sin interrupciones creo que esto haria el trabajo.
Usando tu codigo y minimos cambios

Código: C
  1. #Include <16F877A.h>                
  2. #Fuses XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP   //Configuracion de fusibles
  3. #Use delay (clock=4000000)  //reloj=4Mhz
  4. #Use fast_io(A)    
  5. #Byte portb=6
  6. #Byte porta=2  
  7. #Byte portc= 7
  8. #Define uno portc,0 //Definición de variables
  9. #Define dos portc,1 //Definición de variables                    
  10.  
  11.  
  12. int i=0, j=0;   //displays
  13. void mostrar( )
  14. {
  15.    int display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
  16.  
  17.  
  18.    portb =(display[i]);
  19.    bit_set (uno); //prendo el primer display
  20.    delay_ms(1);
  21.    bit_clear(uno); //lo apago
  22.    portb=(display[j]);
  23.    bit_set (dos); //perdo el segundo
  24.    delay_ms(1);
  25.    bit_clear(dos);    
  26.          
  27. }    
  28. void pulsadores(){                            //Funcion de conteo de eventos
  29.   if(input(pin_A0)){                     //Esta cerrado el pulsador?
  30.     delay_ms(5);                          //Si, elimina rebotes
  31.     i++;
  32.     if (i>9){                      //hasta que sea 9
  33.       i=0;                         //borra unidades e
  34.       j++;                          //incrementa las decenas
  35.         if(j>9){                    //hasta 9
  36.           j=0;                      //borra las decenas
  37.         }
  38.     }
  39.   }            
  40.  
  41. while (bit_test(porta,0)==0){           //Espera visualizando datos , podria usar: while (!input(pin_A0)){ mostrar();}
  42.   mostrar();                            //mientras la tecla esta presionada
  43.   }
  44.      if(input(pin_A1)){                  //Esta cerrado el pulsador?
  45.         delay_ms(5);                      //Si, elimina rebotes
  46.         i=0; j=0;            //reset
  47.      }
  48. }
  49.  
  50. void main(){
  51.                          
  52. set_tris_b(0);                         //portb como salida
  53. set_tris_a(255);                         //RA0 y RA1 entradas
  54. disable_interrupts(GLOBAL);               //activadas interrupciones
  55.  
  56. do{                                       //bucle...
  57.      mostrar();                        
  58.      pulsadores();                          
  59. }while(TRUE);                            
  60. }

Esto tiene algunas desventajas:
Si tenes presionado el boton de aumentar del contador, no podes resetearlo.
El display se encuentre encendido 1ms y luego se apaga por 1ms + tiempo del programa. Esto no supone problema ya que el programa es corto, fuera mucho mas largo o si requiere mucha mas operaciones matematicas por ahi puede influir y conviene con interrupciones. Pero no te compliques todavia y eso miralo cuando lo necesites o cuando quieras aprenderlo.

Errores que vi en tu codigo:

Código: C
  1. digito1=cont%10;
  2.    digito2=cont/10;

digito1,cont y digito2 no estaban definidas, ademas no las usabas, asi que las elimine. No tiene sentido tener una variable contador y luego sacar esos valores si lo estas haciendo 1 varaible para decenas y otra para unidades ( i y j )

en tu codigo no aumentabas i (unidades), cuando entraba al if, sino que aumentaba cont, lo cual vuelvo a repetir no usabas y la condicion del if i>9 jamas se iba a cumplir, por lo cual nunca iba a aumentar. Asi que lo cambie por i++.

Y no es un error pero si te pones a pensar

Código: C
  1. if(input(pin_A1)){                  //Esta cerrado el pulsador?
  2.         delay_ms(5);                      //Si, elimina rebotes
  3.         i=0; j=0;            //reset
  4.      }

Ese delay no tiene importancia, por mas que sirva de antirebote, si entra 100 veces el resultado va a ser i=0 y j=0, distinto el de aumentar la variable que ahi SI preocupa que entre varias veces. Asi que es posible eliminar ese delay y aprovechar el tiempo del micro un poco mas.
« Última modificación: 07 de Junio de 2015, 19:56:52 por KILLERJC »

Desconectado JP0010

  • PIC10
  • *
  • Mensajes: 3
Re: Ayuda contador de 00 - 99 con boton?
« Respuesta #2 en: 07 de Junio de 2015, 22:42:52 »
Gracias amigo, voy a ver y leer bien los cambios que hiciste las verdad es para un proyecto que implica lo que estoy pidiendo y algo mas pero primero estoy empezando a aprender como funciona cada cosa por separado, por eso si puedes me explicarme como usar con interrupciones  porque la verdad que vi varios tutoriales y vídeos de del timer0 y interrupciones externas pero no entendi mucho ya que tomaba cual quier interrupción y la idea es que por ejemplo: pina0 incremente el contador y otro pina1 decrementa, es decir los que vi no decia si las interrupciones se podían especificar por pin.

gracias por la ayuda, ahora a ver los cambios y entender cualquier duda te pregunto que hiciste  :D ((:-))

PD- si un pelon ahi con los cont la verdad fue que copie y pegue de otro codigo y no modifique pero era para mostrar el valor por display.


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Ayuda contador de 00 - 99 con boton?
« Respuesta #3 en: 08 de Junio de 2015, 00:15:23 »
Yo lo diej para que tengas en cuenta que si en tu otra parte del codigo segui agregando delays los displays quedarian asi:

Display 1 :

Tiempo encendido: 1ms
Tiempo apagado: 1ms(dislpay2) + lo que ocupe hacer el otro codigo.

Si se te ocurre poner varios delays, vas a tener el problema que los displays se lo pasan mas apagados que encendidos, una solucion simple seria agrandar el valor de tiempo de encendido de los displays con respecto al de apagado.
La otra es usar interrupciones, pero como dije, no te compliques si no las necesitas, si ves que es necesario entonces se utilizan.

Desconectado JP0010

  • PIC10
  • *
  • Mensajes: 3
Re: Ayuda contador de 00 - 99 con boton?
« Respuesta #4 en: 08 de Junio de 2015, 20:58:54 »
Yo lo diej para que tengas en cuenta que si en tu otra parte del codigo segui agregando delays los displays quedarian asi:

Display 1 :

Tiempo encendido: 1ms
Tiempo apagado: 1ms(dislpay2) + lo que ocupe hacer el otro codigo.

Si se te ocurre poner varios delays, vas a tener el problema que los displays se lo pasan mas apagados que encendidos, una solucion simple seria agrandar el valor de tiempo de encendido de los displays con respecto al de apagado.
La otra es usar interrupciones, pero como dije, no te compliques si no las necesitas, si ves que es necesario entonces se utilizan.


Sigue sin funcionar te paso la simulacion y el codigo es el que viste.
uso proteus 8 Link