Contador ascendente/descendente con un solo push botton

#1
¿Qué tal? Tengo un proyecto que cuenta en ascendencia y muestra la cuenta en un display de 7 segmentos de ánodo común.
Quisiera que contara en descendencia y seleccionar el modo con un solo push button, que con un toque cuente ascendente y con otro descendente y así sucesivamente.
Estoy programando el PIC16F877A en PIC C

Espero puedan ayudarme. De antemano, muchas gracias.
PHP:
#include <16f877a.h>
#use delay (clock = 4000000)

#byte p_b = 6

void main (void)
{ 
     int c;
     int display [10]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xb8,0x80,0x98};
     set_tris_b (0x00);
     c=0;
      while(TRUE) {
         output_b(display[ c ]);
         delay_ms (500);
         c++;
         if (c>9)
         {
           c=0;
         }
       }
}
 
#2
Disculpen, amigos. Tengo este problema.
Necesito hacer un contador en un PIC con esta condición; si pulso una vez el botón, empiece a contar ascendente y si lo vuelvo a pulsar, que cuente descendente.
La dificultad es que es un solo botón y no se me ocurre como hacerlo.

Aquí está mi código:

PHP:
#include <16f877A.h> // busca la librería del dispositivo
#use delay (clock = 4000000) //configura el dispositivo para operar esta frecuencia
#use fast_io(b)
#byte puerto_b = 06 //la variable de nombre puerto_b esta apuntando

#use standard_io(A)

///DECLARACION DE FUNCIONES
void up(void);      //funcion cuenta ascendente
void down(void);   //funcion cuenta descendente

///DECLARACION VARIABLES GLOBALES
signed char i;   //contador para tabla 7 seg (se tiene en cuenta el signo)
int tab7seg[10]={0x3F,6,91,79,102,109,125,7,127,103};   //7seg binario 0-9
      
///PROGRAMA
void main(void)
{
   set_tris_a(0xFF);            //porta como entrada   
   set_tris_b(0x00);            //portb como salida
   disable_interrupts(GLOBAL);      //todas las interrupciones desactivadas
///inicializamos el contador   
   if(!input(PIN_A0))      //para ello leemos el estado del pin A0 del porta
      i=10;            //contador descendente
   else
      i=i--;            //contador ascendente

   do{                        //bucle...
      if(input(PIN_A0))         //¿switch abierto?
         up();               //SI -> contador ascendente
      else// pregunta dos veces ...
         down();//NO -< contador descendente
         
      output_b(tab7seg[ i ]);     //muestra por portb dígito 7 segmentos
      delay_ms(500);
      }while(TRUE);            //...infinito         
}

void up(void)                  //función cuenta ascendente
{         
      i++;                  //incremento contador para visualizar siguiente dígito
      if(i>9)                  //¿ya se ha mostrado el dígito 9?
         i=0;               //SI -< vuelve a empezar(dígito 0)         
}

void down(void)                  //función cuenta descendente
{
      i--;                  //decremento contador para visualizar siguiente dígito
      if(i==-1)               //¿ya se ha mostrado el dígito 0?
         i=9;               //SI -< vuelve a empezar(dígito 9)
}
 
Última edición por un moderador:
#3
Hola!

Te recomendaría usar una interrupción, que con el botón controles una variable global y en las interrupción que sólo pueda tomar dos valores.

Ejemplo:
PHP:
int contbot = 0; //Contador botón

void Interrput(){

  contbot += 1;

  if (contbot >= 2){  // De esta manera contbot solo valdrá 0 o 1

    contbot = 0;
  
  }

IntFlag = 0;  // Bandera interrupción igual a 0 para salir de la interrupción.

 }

seguido de este, en tu función principal un case con tus funciones up y down

void main (){

switch contbot {   // Switch con la variable global del botón.
 case 0; up() ; break;
 case 1; down(); break;         
}

}
Espero haberte ayudado! Saludos
 
Última edición por un moderador:
Arriba