Contador 0 a 99 con PIC y displays de 7 segmentos

Buenas a todos, quería aportarles este humilde trabajillo que hice recientemente, el cual se puede aplicar a cualquier proyecto que necesite un contador de 0 a 99 para visualizar algo.

Les dejo todos los archivos necesarios, no es la gran cosa, pero estoy seguro que a alguien le servirá
 

Adjuntos

  • Proteus.rar
    18.3 KB · Visitas: 427
Última edición por un moderador:
no se achique amigo, todo aporte es bueno y seguramente ayudara a otro, a realizar su proyecto.....
buen trabajo!!!(y)
 
pues gracias men, pues yo hace como 8 años hice un programita muy pequeño para ayudar con eso de los pic y aun me dan gracias y eso que pense que solo yo lo usaria :LOL:
 
Buen día.

Estoy diseñando un contador 0-99 en BASIC ascendente y descendente con display y he logrado un contador hasta 9, ascendente.
No sé cómo implementar las funciones para lograr un contador hasta 99.

Adjunto diagrama y el código. Su interés es muy importante a fin de culminar este proyecto.

Progama en PicBasic Pro:

Código:
define Osc 4        ' Define el oscilador para un cristal de 4 Mhz.
        
        @device mclr_off 'apago MCLR
        trisa = %11110000
        trisb = %11110000 ' hace salidas solo los bits mas bajos
        numero var byte
        bot var porta.0
        flag var bit
        encerar:
        numero = 0
        display:
        portb = numero
        if bot = 0 then aumentar
        pause 80
        flag = 0
        goto display
        aumentar:
        if flag = 1 then goto display
        flag = 1
        if numero = 9 then encerar
        numero = numero + 1
        goto display
        end
 

Adjuntos

  • 0-99.jpg
    0-99.jpg
    141.6 KB · Visitas: 103
Última edición por un moderador:
Necesitas crear lo siguiente:
Crear una variable del tipo Byte 0 a 255. (Para el contador)
Otras dos variables del tipo Byte. (Una para las decenas y otra para las unidades)
Dos rutinas, una para incrementar y otra para decrementar la variable.
Una rutina para multiplexar los displays. Te recomiendo usar interrupción por desborde del Timer 0.

El procedimiento:
En el bucle principal del programa verificarás el estado de los pulsadores.
Tendrás un limite y un desborde, el tope será al incrementar y el desborde al decrementar la variable.
Cuando incrementas, no debes permitir que la variable pase de 99
Y al decrementar, no debes permitir que ocurra el desborde, porque al bajar de 0 la variable retornará a 255.

Posteriormente separas la variable "Contador" en decenas y unidades usando la instrucción "DIG"
A continuación realizas la mutiplexación de los displays. (No importando el orden para mostrar los dígitos)
Es decir, no tiene importancia si muestras primero las unidades y luego las decenas.
Lo que si es importante es el lugar donde se colocan. (Decenas en el display del lado izquierdo y unidades del lado derecho)

Espero sepas como se realiza el sistema multiplex en displays de 7 segmentos.
Este proceso lo harás durante el desborde del Timer 0, dando un corto tiempo de encendido a cada display para mostrar los dígitos.

No es complicado y el código en Basic tampoco lo es.

Nota:
Si usas la instrucción "LookUp" te puedes ahorrar el decodificador 7447.
Con esta instrucción puedes ir tomando los valores de las decenas y las unidades para obtener los bits de encendido de los segmentos de los displays.
Con esto se usa una tabla de valores para cada tipo de display. (Ánodo o cátodo común)
El valor obtenido lo mandas al puerto B y así compactas el circuito. La desventaja es que se usan 7 pines.
 
Aquí te dejo la función que te ha dicho el compañero, si no usas funciones no importa, lo importante es la tabla "LookUp". El primer byte de la tabla corresponde al cero y la correspondencia de los bit con los segmentos es la siguiente:
byte.0 = a
byte.1 = b
"
"
byte.6 = g
byte.7 = h

'Retorna valor: Byte
'Numero a mascara tipo digito display 7 segmentos
'numero = numero a procesar (0 a 9)
'_get7seg, retorna la mascara de los segmentos a activar
Function _get7seg(_numero As Byte) As Byte
_get7seg = LookUp(0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x80), _numero
End Function

Si te decides a usar dígitos multiplexados los pasos para imprimir en el display son los siguientes:

Apagas dígitos.
Cargas el puerto con el nuevo valor a mostrar.
Iluminas el digito que corresponde.
Antes de realizar más cambios en el display esperar 1mSeg.
Repetir el proceso para el siguiente digito.
 
Última edición:
Buenas tardes necesito ayuda con este contador, resulta que solo encienden los display cuando inicia el conteo ascendente, alguien que por favor lo modifique para que enciendan desde el principio. y ademas es posible migrarlo a un 16f628A?
Muchas gracias
 

Adjuntos

  • Contador 00 99.7z
    18.8 KB · Visitas: 84
  • Codigo.txt
    5.7 KB · Visitas: 82
  • contador 00 99 hex.rar
    488 bytes · Visitas: 64
resulta que solo encienden los display cuando inicia el conteo ascendente, alguien que por favor lo modifique para que enciendan desde el principio
Lo único que tienes que hacer es colocar las siguientes instrucciones en el main después del cambio de banco:
Código:
    bcf    STATUS,5
    movlw    3Fh    ; b'00111111' (Número 0)
    movwf    PORTB
    movwf    PORTC
    ;clrf    PB
    ;clrf    PC
    clrf    conteo
Nota que comenté clrf PB y clrf PC para que el agregado posterior se cumpla.
PB es igual que PORTB y PC es igual que PORTC, así que no tiene caso renombrar un registro cuando se usa la librería del PIC en cuestión.
Ahorrar unas pocas letras en nombres de variables es cosa de flojos.
Además, PC es el nombre de un registro y puede causar confusiones. (PC = Program Counter)
Por suerte en este PIC se usa PCL y PCH, si no, grave error.
PCL = Program Counter Low Byte y PCH = Program Counter High Byte, ya que el registro es de 13 bits.
¿Es posible migrarlo a un 16F628A?
Sí, por supuesto, pero con decodificadores de BCD a 7 segmentos porque faltarían bits en el puerto A.
 
Gracias por contestar, le agradezco la ayuda después de probar en varias posiciones pues no sabia en donde era pues soy nivel 000 :angel: inicia prendido en ceros.
Muchas gracias
bcf STATUS,5
clrf conteo
movlw 3Fh ; b'00111111' (Número 0)
movwf PORTB
movwf PORTC

************************
LE PUSE UN RESET Y FUNCIONA
 

Adjuntos

  • 1567695521880.png
    1567695521880.png
    162.6 KB · Visitas: 67
Última edición:
Buenas tardes, estoy usando un pic 16f877a y pickit2 para poder grabarlo, consigo leerlo y grabarlo correctamente pero al momento de ponerlo a funcionar no hace nada lo vuelvo a colocar en el pickit y aparece en blanco, eso solo pasa con es pic pues los demás funcionan sin problema he grabado 16f628-16f84a.
cual podrá ser el error.
 

Adjuntos

  • WhatsApp Image 2019-09-05 at 8.49.08 PM.jpeg
    WhatsApp Image 2019-09-05 at 8.49.08 PM.jpeg
    165.8 KB · Visitas: 11
  • WhatsApp Image 2019-09-05 at 8.47.42 PM.jpeg
    WhatsApp Image 2019-09-05 at 8.47.42 PM.jpeg
    142.3 KB · Visitas: 13
Los valores de las palabras de configuración que se muestran no son valores válidos para el PIC16F877A
En la verificación se muestra 2F82 y en lectura 2FCF
Ningún tipo de bits seleccionados en la palabra de configuración debe empezar con 2, solo con 1 o 3.

Si estás usando la misma palabra de configuración del programa que subiste...
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC, el valor para esta configuración debe ser 3FF1
Si obtienes un valor diferente a ese después de la verificación, entonces el microcontrolador está dañado.
 
Buenas tardes. Disculpen, tengo un problema con el contador al hacer en descendente, ya que al tratar de invertir el código reducido usado, no me funcionó.
¿
Por favor, podrían ayudarme?
Aquí les dejo el código que hice :
C:
#include <16f628a.h>

#fuses xt
#fuses put
#fuses nowdt
#fuses noprotect
#fuses nomclr

#use delay(internal=4M)

#use delay(clock=4Mhz)
#use standard_io(b)
#use standard_io(a)
int display[10]={0b0000001, 0b1001111, 0b0010010, 0b0000110,0b1001100 ,0b0100100, 0b0100000, 0b0001111, 0b000000, 0b0000100};

void main()
{
int unidad= 0;
int decena= 0;
int tiempo= 5;

output_b(0b00000000);

while(1)
{
if(input(pin_a2)== 1)
   {
   output_a(0b10);
   output_b(display[unidad]);
   delay_ms(tiempo);
   output_a(0b01);
   output_b(display[decena]);
   delay_ms(tiempo);
   }
   else
   {
   delay_ms(5);
   output_a(0b10);
   output_b(display[unidad]);
   output_b(display[unidad]);
   delay_ms(tiempo);
   output_a(0b01);
   output_b(display[decena]);
   delay_ms(tiempo);
 

      if (input(pin_a2)==1)
      {
      unidad++;

      if (unidad>9)
      {
      decena++;
      unidad=0;

      }

    
      if(decena>9)
      {
      decena=0;
      unidad=0;
      }
      }
   }
}
}
 
Atrás
Arriba