Contador de 00 a 99 con PIC18F4550 y Displays de 7 Segmentos

En este proyecto se implementa un contador digital de 00 a 99 utilizando el microcontrolador PIC18F4550, dos displays de 7 segmentos y dos pulsadores. El sistema permite incrementar y decrementar el valor mostrado mediante los pines RA0 y RA1, respectivamente. Además, se emplea multiplexación para controlar ambos displays con un número reducido de pines.

Este tipo de implementación es fundamental en sistemas embebidos, ya que combina control de entradas, procesamiento lógico y manejo eficiente de salidas.

CIRCUITO

Estructura general del programa

El programa se divide en tres bloques principales:

Entrada

Se utilizan dos pulsadores conectados a los pines RA0 y RA1. Estos permiten interactuar con el sistema:

  • RA0 incrementa el contador
  • RA1 decrementa el contador

Procesamiento

El valor del contador se almacena en una variable de tipo unsigned char, permitiendo valores de 0 a 99. Se implementa lógica de conteo circular para evitar desbordamientos.

Salida

Se utilizan dos displays de 7 segmentos controlados mediante multiplexación, lo que permite mostrar dos dígitos utilizando un solo puerto de datos.

Configuración de pines

Configuración digital

ADCON1 = 0x0F;

Esta instrucción configura todos los pines como digitales, lo cual es necesario para que RA0 y RA1 funcionen correctamente como entradas.

Dirección de puertos

TRISD = 0x00;
TRISE = 0x00;
TRISA = 0xFF;
  • PORTD se usa para los segmentos
  • PORTE controla qué display está activo
  • PORTA se usa para leer los pulsadores

Lógica del contador

Incremento

contador++;
if(contador > 99) contador = 0;

Cuando se presiona RA0, el contador aumenta en una unidad. Si supera 99, vuelve a 0, implementando un conteo cíclico.

Decremento

if(contador == 0)
    contador = 99;
else
    contador--;

Al presionar RA1, el contador disminuye. Si está en 0, pasa a 99, manteniendo el ciclo.

Antirrebote de botones

__delay_ms(50);
while(PORTAbits.RA0 == 1);

Se implementa un retardo para evitar lecturas erráticas debido al rebote mecánico del pulsador. Además, se espera a que el botón sea liberado antes de continuar.

Control de los displays

Tabla de segmentos

El programa utiliza una tabla que define qué segmentos encender para cada número del 0 al 9.

const unsigned char tabla[10] = {...};

Cada valor representa la combinación de segmentos necesaria para mostrar un dígito.

Multiplexación

La multiplexación permite controlar ambos displays alternando rápidamente entre ellos:

  1. Se muestra la decena
  2. Se apaga el display
  3. Se muestra la unidad
PORTD = tabla[decena];
PORTEbits.RE1 = 1;

PORTD = tabla[unidad];
PORTEbits.RE0 = 1;

Este proceso ocurre continuamente, generando la ilusión de que ambos displays están encendidos simultáneamente.

PROGRAMA COMPLETO

#define _XTAL_FREQ 8000000
#include <xc.h>
// CONFIG (solo si NO usas config.c, si ya tienes config.c → borra esto)
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
#pragma config MCLRE = ON
// Tabla 7 segmentos (cátodo común)
const unsigned char tabla[10] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
unsigned char contador = 0;
// -------- MOSTRAR EN DISPLAY --------
void mostrar(unsigned char num) {
unsigned char decena = num / 10;
unsigned char unidad = num % 10;
// DECENA
PORTE = 0x00;
PORTD = tabla[decena];
PORTEbits.RE1 = 1;
__delay_ms(5);
// UNIDAD
PORTE = 0x00;
PORTD = tabla[unidad];
PORTEbits.RE0 = 1;
__delay_ms(5);
}
// -------- MAIN --------
void main() {
ADCON1 = 0x0F; // TODO digital
TRISD = 0x00; // segmentos
TRISE = 0x00; // control displays
TRISA = 0xFF; // botones
PORTD = 0x00;
PORTE = 0x00;
contador = 0; // empieza en 00
while(1) {
// ---- RA0 INCREMENTA ----
if(PORTAbits.RA0 == 1) {
__delay_ms(50);
if(PORTAbits.RA0 == 1) {
contador++;
if(contador > 99) contador = 0;
while(PORTAbits.RA0 == 1);
}
}
// ---- RA1 DECREMENTA ----
if(PORTAbits.RA1 == 1) {
__delay_ms(50);
if(PORTAbits.RA1 == 1) {
if(contador == 0)
contador = 99;
else
contador--;
while(PORTAbits.RA1 == 1);
}
}
mostrar(contador);
}
}

 

 

Conclusión

Este proyecto demuestra cómo integrar entradas digitales, lógica de control y visualización en un sistema embebido. La multiplexación permite optimizar el uso de pines, mientras que la gestión de botones introduce conceptos clave como antirrebote y control de estado.

A partir de esta base, es posible escalar el diseño hacia aplicaciones más complejas como relojes digitales, interfaces de usuario o sistemas de monitoreo.

Deja un comentario