// Gian Luca Ramírez - 1096600
// Lab 03 - Cronómetro Digital con displays 7 segmentos.
// Sistemas Digitales y Microprocesadores.
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/timer.h"
// Pines GPIO para los segmentos del display de 7 segmentos (cátodo común)
const uint SEGMENTOS[8] = {0, 1, 2, 3, 4, 5, 6, 7}; // Incluyendo el punto decimal
// Pines GPIO para los dígitos del display (ánodo común)
const uint DIGITOS[4] = {8, 9, 10, 11};
// Pines GPIO para los botones
const uint BOTONES[4] = {12, 13, 14, 15}; // Start/Stop, Set, Increase, Reset
// Estados de los botones
volatile bool boton_presionado[4] = {false, false, false, false};
// Variables del cronómetro
volatile bool corriendo = false;
volatile uint digitos[4] = {0, 0, 0, 0};
volatile int digito_seleccionado = -1; // -1 indica que no hay dígito seleccionado
volatile bool parpadear = false;
// Mapeo de segmentos para cada dígito (0-9)
const uint MAPA_SEGMENTOS[10] = {
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111 // 9
};
void actualizar_display(volatile uint digitos[4]);
bool timer_callback(struct repeating_timer *t);
void button_callback(uint gpio, uint32_t events);
void setup_gpio();
void procesar_botones();
int main() {
stdio_init_all();
setup_gpio();
struct repeating_timer timer;
add_repeating_timer_ms(10, timer_callback, NULL, &timer);
while (1) {
procesar_botones();
actualizar_display(digitos);
}
}
void setup_gpio() {
for (int i = 0; i < 8; i++) {
gpio_init(SEGMENTOS[i]);
gpio_set_dir(SEGMENTOS[i], GPIO_OUT);
}
for (int i = 0; i < 4; i++) {
gpio_init(DIGITOS[i]);
gpio_set_dir(DIGITOS[i], GPIO_OUT);
gpio_init(BOTONES[i]);
gpio_set_dir(BOTONES[i], GPIO_IN);
gpio_pull_up(BOTONES[i]);
gpio_set_irq_enabled_with_callback(BOTONES[i], GPIO_IRQ_EDGE_FALL, true, button_callback);
}
}
void button_callback(uint gpio, uint32_t events) {
for (int i = 0; i < 4; i++) {
if (gpio == BOTONES[i]) {
boton_presionado[i] = true;
break;
}
}
}
bool timer_callback(struct repeating_timer *t) {
static uint contador_parpadeo = 0;
if (corriendo) {
digitos[0]++;
for (int i = 0; i < 3; i++) {
if (digitos[i] >= 10) {
digitos[i] = 0;
digitos[i + 1]++;
}
}
if (digitos[3] >= 10) {
digitos[3] = 0;
}
}
contador_parpadeo++;
if (contador_parpadeo >= 5) {
parpadear = !parpadear;
contador_parpadeo = 0;
}
return true;
}
void procesar_botones() {
if (boton_presionado[0]) {
corriendo = !corriendo;
boton_presionado[0] = false;
}
if (boton_presionado[1]) {
digito_seleccionado = (digito_seleccionado + 1) % 4;
boton_presionado[1] = false;
}
if (boton_presionado[2] && digito_seleccionado != -1) {
digitos[digito_seleccionado] = (digitos[digito_seleccionado] + 1) % 10;
boton_presionado[2] = false;
}
if (boton_presionado[3]) {
corriendo = false;
for (int i = 0; i < 4; i++) {
digitos[i] = 0;
}
digito_seleccionado = -1;
boton_presionado[3] = false;
}
}
void actualizar_display(volatile uint digitos[4]) {
for (int i = 0; i < 4; i++) {
if (i == digito_seleccionado && parpadear) {
for (int j = 0; j < 7; j++) {
gpio_put(SEGMENTOS[j], 0);
}
} else {
uint digito = digitos[i];
for (int j = 0; j < 7; j++) {
gpio_put(SEGMENTOS[j], (MAPA_SEGMENTOS[digito] >> j) & 1);
}
}
if (i == 1) {
gpio_put(SEGMENTOS[7], 1);
} else {
gpio_put(SEGMENTOS[7], 0);
}
gpio_put(DIGITOS[3 - i], 0);
sleep_ms(5);
gpio_put(DIGITOS[3 - i], 1);
}
}