#include "pico/stdlib.h"
#include <stdbool.h>
// --- Definições de Pinos ---
// LEDs do semáforo
#define LED_VERMELHO 17
#define LED_AMARELO 18
#define LED_VERDE 19
// Display de 7 segmentos (catodo comum)
#define DIG_1 7 // dezena
#define DIG_2 8 // unidade
// --- Tabela 7 segmentos (catodo comum) ---
// Bits: GFEDCBA (1 = acender segmento)
const uint8_t TABELA_7SEG[10] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x67 // 9
};
volatile uint8_t display[2];
volatile bool displayOn = false;
// --- Função de multiplexação dos displays ---
bool multiplex_display(struct repeating_timer *t) {
static int digito = 0;
gpio_clr_mask(0x7F); // limpa segmentos (seta LOW em GP0-6)
if (!displayOn) {
gpio_put(DIG_1, 1); // desativa dígitos (HIGH para cátodo comum)
gpio_put(DIG_2, 1);
return true;
}
if (digito == 0) {
gpio_put(DIG_2, 1); // desativa unidade
gpio_put(DIG_1, 0); // ativa dezena (LOW no cátodo)
gpio_set_mask(display[0] & 0x7F); // seta HIGH nos segmentos corretos
digito = 1;
} else {
gpio_put(DIG_1, 1); // desativa dezena
gpio_put(DIG_2, 0); // ativa unidade (LOW no cátodo)
gpio_set_mask(display[1] & 0x7F); // seta HIGH nos segmentos corretos
digito = 0;
}
return true;
}
// Atualiza o valor mostrado nos displays
void atualizar_display(int valor) {
if (valor < 0) valor = 0;
if (valor > 99) valor = 99;
display[0] = TABELA_7SEG[valor / 10];
display[1] = TABELA_7SEG[valor % 10];
}
// --- Função Principal ---
int main() {
// Inicializa pinos dos segmentos GP0–GP6
for (int pin = 0; pin <= 6; pin++) {
gpio_init(pin);
gpio_set_dir(pin, GPIO_OUT);
gpio_put(pin, 0); // inicia LOW
}
// Inicializa pinos dos dígitos
gpio_init(DIG_1);
gpio_set_dir(DIG_1, GPIO_OUT);
gpio_put(DIG_1, 1); // inicia desativado (HIGH)
gpio_init(DIG_2);
gpio_set_dir(DIG_2, GPIO_OUT);
gpio_put(DIG_2, 1); // inicia desativado
// Inicializa LEDs do semáforo
gpio_init(LED_VERMELHO);
gpio_set_dir(LED_VERMELHO, GPIO_OUT);
gpio_put(LED_VERMELHO, 0);
gpio_init(LED_AMARELO);
gpio_set_dir(LED_AMARELO, GPIO_OUT);
gpio_put(LED_AMARELO, 0);
gpio_init(LED_VERDE);
gpio_set_dir(LED_VERDE, GPIO_OUT);
gpio_put(LED_VERDE, 0);
// Timer para multiplexar display (5ms para suavidade)
struct repeating_timer timer;
add_repeating_timer_ms(5, multiplex_display, NULL, &timer);
// Estados do semáforo
enum Estado { VERMELHO, AMARELO, VERDE };
enum Estado estado = VERMELHO; // MUDANÇA: Começa em VERMELHO automaticamente
while (true) {
switch (estado) {
case VERMELHO:
gpio_put(LED_VERDE, 0);
gpio_put(LED_AMARELO, 0);
gpio_put(LED_VERMELHO, 1);
displayOn = true;
for (int i = 20; i >= 0; i--) {
atualizar_display(i);
sleep_ms(1000);
}
estado = VERDE;
break;
case VERDE:
gpio_put(LED_VERDE, 1);
gpio_put(LED_AMARELO, 0);
gpio_put(LED_VERMELHO, 0);
displayOn = true;
for (int i = 15; i >= 0; i--) {
atualizar_display(i);
sleep_ms(1000);
}
estado = AMARELO;
break;
case AMARELO:
gpio_put(LED_VERDE, 0);
gpio_put(LED_AMARELO, 1);
gpio_put(LED_VERMELHO, 0);
displayOn = false;
sleep_ms(5000);
estado = VERMELHO;
break;
}
}
}