Aprende a implementar un contador digital de 0 a 99 utilizando el microcontrolador PIC16F628A programado en lenguaje C con CCS C Compiler. Este proyecto integra multiplexación de displays 7 segmentos, control mediante pulsador y anti-rebote en software, siendo perfecto para iniciarse en el mundo de los microcontroladores PIC.
🎯 Características del Proyecto
- Contador de 0 a 99: Con reset automático al completar ciclo
- Multiplexación: Control de 2 displays 7 segmentos simultáneamente
- Control mediante pulsador: Incremento manual del contador
- Anti-rebote en software: Evita múltiples incrementos por pulsación
- Visualización clara: Refresco a 5ms para flicker imperceptible
📋 Materiales Requeridos
🖥️ Componentes Electrónicos
- PIC16F628A: Microcontrolador principal
- 2 Displays 7 segmentos: Ánodo común
- 2 Transistores 2N2222: Control de multiplexación
- 1 Pulsador: Para incremento del contador
- 1 Resistencia 1kΩ: Limitación de corriente
- Resistencias 330Ω: Para segmentos del display (7 por display)
- Cristal oscilador: 4MHz (opcional, se usa reloj interno)
- Protoboard y cables: Para montaje
🔌 Diagrama de Conexiones
El diagrama esquemático muestra la conexión completa del circuito con el PIC16F628A, los dos displays de 7 segmentos y el pulsador de control:
🔧 Montaje en Protoboard
A continuación se muestra el detalle de conexión de los displays 7 segmentos en la protoboard:
💻 Código Fuente - CCS C Compiler
El código implementa la lógica completa del contador con multiplexación y anti-rebote. Utiliza el puerto A para seleccionar qué display mostrar y el puerto B para enviar los patrones de segmentos:
#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) // Patrones de 7 segmentos para dígitos 0-9 (ánodo común) int display[10] = { 0b0000001, // 0 0b1001111, // 1 0b0010010, // 2 0b0000110, // 3 0b1001100, // 4 0b0100100, // 5 0b0100000, // 6 0b0001111, // 7 0b0000000, // 8 0b0000100 // 9 }; void main() { int unidad = 0; int decena = 0; int tiempo = 5; boolean estadoPrevio; output_b(0b00000000); while (1) { // Mostrar unidades (display derecho) output_a(0b10); output_b(display[unidad]); delay_ms(tiempo); // Mostrar decenas (display izquierdo) output_a(0b01); output_b(display[decena]); delay_ms(tiempo); // Detección de pulsación con anti-rebote if (input(PIN_A2) != estadoPrevio) { if (input(PIN_A2) == 1) { unidad++; } } delay_ms(5); // Lógica del contador - incrementar decenas if (unidad > 9) { decena++; unidad = 0; } // Reset automático al llegar a 99 if (decena > 9) { decena = 0; unidad = 0; } estadoPrevio = input(PIN_A2); } }
🔍 Explicación Detallada del Código
📊 Configuración del Microcontrolador
- #fuses XT: Oscilador externo (si usas cristal)
- #fuses PUT: Power-Up Timer (espera antes de ejecutar)
- #fuses NOWDT: Desactiva el watchdog timer
- #fuses NOPROTECT: Memoria no protegida
- #fuses NOMCLR: MCLR como entrada normal
🔢 Array de Patrones 7 Segmentos
Cada número (0-9) tiene un patrón binario específico que activa los segmentos correctos. Para displays de ánodo común, un bit en 0 enciende el segmento:
0 = 0b0000001 (a,b,c,d,e,f) 1 = 0b1001111 (b,c) 2 = 0b0010010 (a,b,d,e,g) ...y así sucesivamente
🔄 Multiplexación de Displays
El sistema alterna entre mostrar decenas y unidades cada 5ms:
- output_a(0b10) → Activa display derecho (unidades)
- output_a(0b01) → Activa display izquierdo (decenas)
- delay_ms(5) → Refresco cada 5ms
⚙️ Lógica del Anti-Rebote
El anti-rebote se implementa comparando el estado actual del botón con el estado anterior. Solo se incrementa el contador cuando detecta una transición de bajo a alto:
// Detección de cambio de estado if (input(PIN_A2) != estadoPrevio) { // Solo incrementa al presionar (transición 0→1) if (input(PIN_A2) == 1) { unidad++; } } // Guardar estado para siguiente ciclo estadoPrevio = input(PIN_A2);
| Función | Descripción | Resultado |
|---|---|---|
| output_a() | Selecciona qué display mostrar | 0b01 o 0b10 |
| output_b() | Envía patrón de segmentos | Patrón 7 segmentos |
| input() | Lee estado del pulsador | 0 (no presionado) o 1 (presionado) |
| delay_ms() | Pausa en milisegundos | Tiempo de espera |
🔧 Consejos de Implementación
✅ Buenas Prácticas
- Verifica los fuses: Según tu cristal (XT, HS, RC)
- Ajusta los delays: Modifica "tiempo" (5ms) si hay parpadeo
- Resistencias limitadoras: 330Ω mínimo para segmentos del display
- Prueba anti-rebote: Experimenta con diferentes valores de delay
- Usa transistores correctos: 2N2222 o equivalente NPN
- Polaridad correcta: Ánodo común necesita lógica invertida
⚠️ Solución de Problemas
- Display no enciende: Verificar conexiones de transistores
- Parpadeo excesivo: Reducir valor de "tiempo"
- Contador no incrementa: Revisar conexión del pulsador
- Incrementos múltiples: Aumentar delay de anti-rebote
- Segmentos incorrectos: Validar patrones del array display[]
🚀 Mejoras y Extensiones
Ideas para Expandir el Proyecto
- Botón de reset: Agregar segundo pulsador para poner contador en 0
- Velocidad variable: Cambiar velocidad de conteo con potenciómetro
- Decremento: Segundo botón para contar hacia atrás
- Almacenamiento: Guardar valor máximo en EEPROM
- Más displays: Expandir a contador de 3 o 4 dígitos
- Alarma: Sonido o LED cuando se alcanza un valor
Accede al código fuente optimizado, simulación en Proteus y documentación técnica
🎓 Lo que has Aprendido
Al completar este proyecto, dominas la multiplexación de displays 7 segmentos, el manejo de puertos de entrada/salida del PIC16F628A, la implementación de anti-rebote en software y la programación básica en C para microcontroladores PIC usando CCS C Compiler. Estas habilidades son fundamentales para proyectos más complejos de control digital.
Publicar un comentario
¡Hola! Nos alegra mucho que hayas llegado hasta aquí y que estés leyendo este artículo en Edeptec.
Este formulario es un espacio abierto para ti: puedes dejar un comentario con tus dudas, sugerencias, experiencias o simplemente tu opinión sobre el tema tratado.
» ¿Te resultó útil la información?
» ¿Tienes alguna experiencia personal que quieras compartir?
» ¿Se te ocurre algún tema que te gustaría ver en próximos artículos?
Recuerda que este espacio es para aprender y compartir, por eso te animamos a participar de manera respetuosa y constructiva. Tus comentarios pueden ayudar a otros lectores que están en el mismo camino, ya sea en electrónica, programación, deportes o tecnología.
¡Gracias por ser parte de esta comunidad de aprendizaje! Tu participación es lo que hace crecer este proyecto.