Contador up/down para 16F877

He realizado el siguiente codigo para un contador up/down de dos digitos,codigo de programacio C, y entorno MPLAB.

El contador debe hacer el decremento o incremento de los numeros aproximadamente cada un segundo.

Un pulsador debe hacer cambiar el sentido del contador con cada pulsacion, pero a mi solamente me lo hace en la primera pulsacion.

Os agradeceria que si detectais el fallo me ayudarais a que em funcionara correctamente.
Gracias de antemano. Un saludo.



#include <16F877.H> // Librería
#use delay(clock=4000000) // Reloj. Usado para cálculos de tiempo.
#fuses XT,NOWDT,NOPROTECT // Palabra de configuración

// Configuración de pines como salida.
#use fast_io(A)
#use fast_io(D)

#bit PUL1 = 5.0
#bit DISPLAY1 = 5.2 //configuracion del pin del pulsador(5.0) y de lso displays
#bit DISPLAY2 = 5.3
#byte PORT_D = 8

const int display[16]={0x3F,0x06,0x5B,0x4F, // Al ser un vector constante
0x66,0x6D,0x7D,0x27, // se crea dentro de la memoria
0x7F,0x6F,0x77,0x7C, // de programa.
0x39,0x5E,0x79,0x71};



/**********************
* VARIABLES GLOBALES
**********************/
int tiempo;
int cambio;


/***************************************
* DEFINICIONES DE FUNCIONES LOCALES
***************************************/

char Pulsador(void);
void Control(void);
void MuestraNumero(int Num);

/*********************
* FUNCION PRINCIPAL
*********************/

main()
{
signed int Numero;

// Configuración de pines como entrada o salida. 0=salida, 1=entrada
set_tris_a(0x03); //Para los Pulsadores
set_tris_D(0x00); //Para los Displays

// Inicialización.
Numero = 0;
cambio=0;
tiempo=0;

while (1)
{
Pulsador();
Control();
if (cambio== 0)
{
if (tiempo>=125)
{
tiempo=0;
//Incremento contador
Numero++;
if (Numero > 99)
{
Numero = 0;
}
else
tiempo++;
}
}
if (cambio== 1)
{
if (tiempo>=125)
{
tiempo=0;
//Decremento contador
Numero--;
if (Numero < 0)
{
Numero = 99;
}
else
tiempo++;
}
}

MuestraNumero(Numero);
}
}

// Subrutina para la deteccion del pulsador
char Pulsador(void)
{
static char M_PUL1;
char bAccion;
static byte Time; //multiplos de 5ms * el Nº Digitos

//Inicializacion
bAccion = 0;
M_PUL1=0;

// Deteccion cuando pulsa pulsador
if (M_PUL1==0 && PUL1==1)
{
if (Time >= 2)//delay_ms(20);
{
if (PUL1==1)
{
M_PUL1=1;
bAccion=1;
}
Time = 0;
}
else
Time++;
}

// Deteccion cuando suelta pulsador
if (M_PUL1==1 && PUL1==0)
{
if (Time >= 2)//delay_ms(20);
{
if (PUL1==0)
{
M_PUL1=0;
}
Time = 0;
}
else
Time++;
}
return (bAccion);
}


void Control(void)
{
if (pulsador()==1 && cambio==1)
{
cambio=0;
}

if (pulsador()==1 && cambio==0)
{
cambio=1;
}
}



void MuestraNumero(int Num)
{
byte Num1, Num2;

Num1 = Num % 10;
Num2 = Num / 10;

PORT_D = Display[Num1];
DIS1 = 1;
Delay_ms(4);
DIS1 = 0;

PORT_D = Display[Num2];
DIS2 = 1;
Delay_ms(4);
DIS2 = 0;
}
 
El problema está en que en la función pulsador() inicializas la variable estática M_PUL1, con lo que ya no retiene el valor entre llamadas, como si no fuera estática.
Usa la función opción CODE del foro para poder postear fuentes sin que pierdan el formato.
También he comentado unas líneas que no sé si son un error, no he simulado el programa. Este Este es el código modificado:
Código:
#include <16F877.H> // Librería
#use delay(clock=4000000) // Reloj. Usado para cálculos de tiempo.
#fuses XT,NOWDT,NOPROTECT // Palabra de configuración

// Configuración de pines como salida.
#use fast_io(A)
#use fast_io(D)

#bit PUL1 = 5.0
#bit DIS1 = 5.2 //configuracion del pin del pulsador(5.0) y de lso displays
#bit DIS2 = 5.3
#byte PORT_D = 8

const int display[16]={0x3F,0x06,0x5B,0x4F, // Al ser un vector constante
0x66,0x6D,0x7D,0x27, // se crea dentro de la memoria
0x7F,0x6F,0x77,0x7C, // de programa.
0x39,0x5E,0x79,0x71};


/**********************
* VARIABLES GLOBALES
**********************/
int tiempo;
int cambio;


/***************************************
* DEFINICIONES DE FUNCIONES LOCALES
***************************************/

char Pulsador(void);
void Control(void);
void MuestraNumero(int Num);

/*********************
* FUNCION PRINCIPAL
*********************/

main()
{
	signed int Numero;

	// Configuración de pines como entrada o salida. 0=salida, 1=entrada
	set_tris_a(0x03); //Para los Pulsadores
	set_tris_D(0x00); //Para los Displays

	// Inicialización.
	Numero = 0;
	cambio=0;
	tiempo=0;

   while (1)
   {
      Pulsador();
      Control();
      if (cambio== 0)
      {
         if (tiempo>=125)
         {
            tiempo=0;
            //Incremento contador
            Numero++;
            if (Numero > 99) Numero = 0;
          //  else tiempo++;    no se si así te funcionara, pero yo lo pondria
         }
         else tiempo++;  //  aqui, creo que es lo correcto
      }
      if (cambio== 1)
      {
         if (tiempo>=125)
         {
            tiempo=0;
            //Decremento contador
            Numero--;
            if (Numero < 0) Numero = 99;
          //  else tiempo++;  no se si así te funcionara, pero yo lo pondria
         }
         else tiempo++;  //  aqui, creo que es lo correcto
      }
      MuestraNumero(Numero);
   }
}

// Subrutina para la deteccion del pulsador
char Pulsador(void)
{
   static char M_PUL1;
   char bAccion;
   static byte Time; //multiplos de 5ms * el Nº Digitos

   //Inicializacion
   bAccion = 0;
 //  M_PUL1=0;   El fallo esta aquí, si lo inicializas no retiene el valor de
              // una llamada a la funcion a otra, es como si no fuera static.  

   // Deteccion cuando pulsa pulsador
   if (M_PUL1==0 && PUL1==1)
   {
      if (Time >= 2)//delay_ms(20);
      {
         if (PUL1==1)
         {
            M_PUL1=1;
            bAccion=1;
         }
         Time = 0;
      }
      else Time++;
   }

   // Deteccion cuando suelta pulsador
   if (M_PUL1==1 && PUL1==0)
   {
      if (Time >= 2)//delay_ms(20);
      {
         if (PUL1==0)
         {
            M_PUL1=0;
         }
         Time = 0;
      }
      else Time++;
   }
   return (bAccion);
}


void Control(void)
{
   if (pulsador()==1 && cambio==1)
   {
      cambio=0;
   }

   if (pulsador()==1 && cambio==0)
   {
      cambio=1;
   }
}



void MuestraNumero(int Num)
{
   byte Num1, Num2;

   Num1 = Num % 10;
   Num2 = Num / 10;

   PORT_D = Display[Num1];
   DIS1 = 1;
   Delay_ms(4);
   DIS1 = 0;

   PORT_D = Display[Num2];
   DIS2 = 1;
   Delay_ms(4);
   DIS2 = 0;
}
Agradecería que me dijeras si funciona...
 
Muchas gracias heli.

No tengo posibilidad de probarlo hasta el Lunes porque necesito una fuente de alimentacion a 5 voltios.

El lunes ire al taller de la universidad y lo probare y te comentare si me funciona.

Te lo agradezco mucho porque me juego la vida con esto jajaja

un saludo!!

Hasta el lunes.
 
Atrás
Arriba