Autor Tema: Cronometro usando int rb y dos display  (Leído 2370 veces)

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

Desconectado Trev_11

  • PIC10
  • *
  • Mensajes: 44
Cronometro usando int rb y dos display
« en: 04 de Octubre de 2008, 12:45:48 »
Hola quiero hacer un cronometro con dos display 7 segmentos pero no me funciona muy bien con los ciclos for,primero
se ingresa un numero de 0 a 99,oprimiendo la tecla numeral debe decrementar dicho valor hasta 0,me parece q el problema esta en mi funcion decremento q no consigo mejorarla,si alguien me puede orientar gracias :)
Código: [Seleccionar]
#include <16f877.h>
#fuses XT,PUT,BROWNOUT,NOPROTECT,NOLVP,NOWDT
#use delay(clock=4000000)
#byte portb=0x06
#byte portc=0x07
#byte portd=0x08


int digitos=0,tecla_pulsada,unidades,decenas;
int DISPLAY[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
int escan_teclado();  /*Prototipo de la función escan_teclado*/
void decremento();

#int_rb   //CCS habilita(una vez fuera)e inhabilita(para ke no se produzca de nuevo la int. mientras se la trata) la int. automaticamente.
void VER_TECLA(void)
{
   switch(digitos)
   {
   case 0:
   tecla_pulsada=escan_teclado();
      if(tecla_pulsada==11)
      {
      decremento();
      decenas=tecla_pulsada;
      break;
      }
     
     
      else
      {
      digitos=1;
      decenas=tecla_pulsada;
      }
   portd=DISPLAY[tecla_pulsada];
   while(!bit_test(portb,4)||!bit_test(portb,5)||!bit_test(portb,6))
   {
   
   }
   break;
   case 1:
   tecla_pulsada=escan_teclado();
      if(tecla_pulsada==11)
      {
      decremento();
      unidades=tecla_pulsada;
      break;
      }
     
     
      else
      {
      unidades=tecla_pulsada;
      digitos=0;
      }
   portc=DISPLAY[tecla_pulsada];
   while(!bit_test(portb,4)||!bit_test(portb,5)||!bit_test(portb,6))
   {
   
   }
   break;
   }
   
#asm
movf portb,0;
#endasm

}

main()
{
   set_tris_b(0xf0);
   set_tris_c(0x00);
   set_tris_d(0x00);
   portb=0xf0;
   enable_interrupts(global);
   enable_interrupts(int_rb);
   portc=DISPLAY[0];
   portd=DISPLAY[0];
   port_b_pullups(TRUE);
   while(1)
   {
 
   }
}

int escan_teclado()
{
     int tecla=0,PULSACION=0;
     int i=0;
     int vect[5]={0x0E,0x0D,0x0B,0x07,0};
     int matriz_teclado[4][3]={1,2,3,4,5,6,7,8,9,0,0,11};
     PULSACION=0;
     while(PULSACION==0)
          {
          portb=vect[i];
          if(input(PIN_B4)==0)
                {
                 tecla=0;
                 tecla=matriz_teclado[i][tecla];
                 PULSACION=1;
                }
          if(input(PIN_B5)==0)
                {
                 tecla=1;
                 tecla=matriz_teclado[i][tecla];
                 PULSACION=1;
                }
          if(input(PIN_B6)==0)
                {
                 tecla=2;
                 tecla=matriz_teclado[i][tecla];
                 PULSACION=1;
                }
          ++i;
          if(i==4)
          i=0;
          }
     portb=0xf0;     
     return(tecla);
}

void decremento()
{
int j,k;
   if(unidades!=0)
   {
   k=decenas;
      while(k!=0)
         {
         --k;
         portd=DISPLAY[k];
            for(j=unidades;j!=0;j--)
            {
            portc=DISPLAY[j];
            delay_ms(1000);
            }
          unidades=9;
          portc=DISPLAY[0];
          delay_ms(1000);
         }     
   }
   else if(unidades==0)
   {
   k=decenas;
      while (k!=0)
         {
         --k;
         portd=DISPLAY[k];
            for(j=9;j!=0;j--)
               {
               portc=DISPLAY[j];
               delay_ms(1000);
               }
         portc=DISPLAY[0];
         delay_ms(1000);
         }     
   }

}

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Cronometro usando int rb y dos display
« Respuesta #1 en: 04 de Octubre de 2008, 14:09:33 »
hola

creo que seria mejor usar una interrupcion para decrementar el tiempo.

saludos
El papel lo aguanta todo

Desconectado Trev_11

  • PIC10
  • *
  • Mensajes: 44
Re: Cronometro usando int rb y dos display
« Respuesta #2 en: 04 de Octubre de 2008, 16:12:39 »
Hola,gracias por responder aca introduzco una mejora todavia falta depurar pero por lo menos ya hace lo que
busco  :)
Código: [Seleccionar]
#include <16f877.h>
#fuses XT,PUT,BROWNOUT,NOPROTECT,NOLVP,NOWDT
#use delay(clock=4000000)
#byte portb=0x06
#byte portc=0x07
#byte portd=0x08


int digitos=0,tecla_pulsada,unidades,decenas;
int DISPLAY[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
int escan_teclado();  /*Prototipo de la función escan_teclado*/
void decremento();

#int_rb   //CCS habilita(una vez fuera)e inhabilita(para ke no se produzca de nuevo la int. mientras se la trata) la int. automaticamente.
void VER_TECLA(void)
{
   switch(digitos)
   {
   case 0:
   tecla_pulsada=escan_teclado();
      if(tecla_pulsada==11)
      {
      decremento();
      decenas=tecla_pulsada;
      break;
      }
     
     
      else
      {
      digitos=1;
      decenas=tecla_pulsada;
      }
   portd=DISPLAY[tecla_pulsada];
   while(!bit_test(portb,4)||!bit_test(portb,5)||!bit_test(portb,6))
   {
   
   }
   break;
   case 1:
   tecla_pulsada=escan_teclado();
      if(tecla_pulsada==11)
      {
      decremento();
      unidades=tecla_pulsada;
      break;
      }
     
     
      else
      {
      unidades=tecla_pulsada;
      digitos=0;
      }
   portc=DISPLAY[tecla_pulsada];
   while(!bit_test(portb,4)||!bit_test(portb,5)||!bit_test(portb,6))
   {
   
   }
   break;
   }
   
#asm
movf portb,0;
#endasm

}

main()
{
   set_tris_b(0xf0);
   set_tris_c(0x00);
   set_tris_d(0x00);
   portb=0xf0;
   enable_interrupts(global);
   enable_interrupts(int_rb);
   portc=DISPLAY[0];
   portd=DISPLAY[0];
   port_b_pullups(TRUE);
   while(1)
   {
 
   }
}

int escan_teclado()
{
     int tecla=0,PULSACION=0;
     int i=0;
     int vect[5]={0x0E,0x0D,0x0B,0x07,0};
     int matriz_teclado[4][3]={1,2,3,4,5,6,7,8,9,0,0,11};
     PULSACION=0;
     while(PULSACION==0)
          {
          portb=vect[i];
          if(input(PIN_B4)==0)
                {
                 tecla=0;
                 tecla=matriz_teclado[i][tecla];
                 PULSACION=1;
                }
          if(input(PIN_B5)==0)
                {
                 tecla=1;
                 tecla=matriz_teclado[i][tecla];
                 PULSACION=1;
                }
          if(input(PIN_B6)==0)
                {
                 tecla=2;
                 tecla=matriz_teclado[i][tecla];
                 PULSACION=1;
                }
          ++i;
          if(i==4)
          i=0;
          }
     portb=0xf0;     
     return(tecla);
}

void decremento()
{
if(decenas==0)
{
portd=DISPLAY[decenas];
            while(unidades!=0)
            {
            portc=DISPLAY[unidades];
            delay_ms(1000);
            --unidades;
            }
         portc=DISPLAY[unidades];
         delay_ms(1000);   
}
while(decenas!=0)
      {
      portd=DISPLAY[decenas];
         while(unidades!=0)
         {
         portc=DISPLAY[unidades];
         delay_ms(1000);
         --unidades;
         }
      portc=DISPLAY[unidades];    /*Al salir del while el valor de unidades es 0*/
      delay_ms(1000);             
      unidades=9;
      --decenas;
      if(decenas==0)
         {
         portd=DISPLAY[decenas];
            while(unidades!=0)
            {
            portc=DISPLAY[unidades];
            delay_ms(1000);
            --unidades;
            }
         portc=DISPLAY[unidades];
         delay_ms(1000);   
         }
      }
}     

 

..pero me gustaria ver tu idea a ver si es mas compacta,salu2

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Cronometro usando int rb y dos display
« Respuesta #3 en: 04 de Octubre de 2008, 16:19:07 »
Hola.

Pues yo manejo los display de 7 segmentos con el timer0 (http://www.todopic.com.ar/foros/index.php?topic=21738.0).

La asignacion de los valores lo haria en el programa principal, y tendria un boton de inicio para activar las interrupciones del Timer1 para decrementar el tiempo,de esa manera decremento la variable global (minutos y segundos).

Saludos
El papel lo aguanta todo