// ALUNO: JOSICLEYTON AZEVEDO DOS SANTOS
// CAPACITAÇÃO EM SISTEMAS EMBARCADOS
// POLO NATAL
// TAREFA DA UNIDADE III
// LINGUAGENS E AMBIENTES DE PROGRAMAÇÃO
////////////////////////////////////////////////////////
// BIBLIOTECAS UTILIZADAS
////////////////////////////////////////////////////////
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
// Definições de GPIOs
#define BUZZER 0
#define LED_PEDESTRE_VERDE 1
#define BOTAO_PEDESTRE 2
#define LED_VERMELHO 9
#define LED_AMARELO 10
#define LED_CARRO_VERDE 12
// Definição da frequência
#define FREQUENCIA_BUZZER 400
////////////////////////////////////////////////////////
// VARIÁVEIS GLOBAIS
////////////////////////////////////////////////////////
uint slice_buzzer;
volatile bool pedestre_esperando = false; // Flag para indicar solicitação de pedestres
////////////////////////////////////////////////////////
// FUNÇÕES AUXILIARES
////////////////////////////////////////////////////////
// (1)) Inicializa um botão configurado como entrada
void inicializar_botao(int gpio) {
gpio_init(gpio);
gpio_set_dir(gpio, GPIO_IN);
gpio_pull_down(gpio);
}
// (2) Inicializa um LED configurado como saída
void inicializar_led(int gpio) {
gpio_init(gpio);
gpio_set_dir(gpio, GPIO_OUT);
gpio_put(gpio, 0);
gpio_set_slew_rate(gpio, GPIO_SLEW_RATE_SLOW);
}
// (3) Inicializa o PWM para o buzzer
void inicializar_pwm_buzzer(int gpio) {
uint32_t clock = 125000000;
gpio_set_function(gpio, GPIO_FUNC_PWM);
slice_buzzer = pwm_gpio_to_slice_num(gpio);
uint32_t wrap_value = clock / FREQUENCIA_BUZZER - 1; // Calcula o valor de wrap
pwm_set_wrap(slice_buzzer, wrap_value); // Define o valor máximo do contador
pwm_set_chan_level(slice_buzzer, PWM_CHAN_A, wrap_value / 2); // 50% de duty cycle
}
// (4) Callback da interrupção do botão de pedestres
void botao_pedestre_callback(uint gpio, uint32_t events) {
pedestre_esperando = true; // Define a flag quando o botão é pressionado
}
// (5) Controla o sistema de pedestres
void ativar_sistema_pedestre() {
// Liga o LED verde para pedestres e o vermelho para carros
gpio_put(LED_AMARELO, 0);
gpio_put(LED_PEDESTRE_VERDE, 1);
gpio_put(LED_VERMELHO, 1);
pwm_set_enabled(slice_buzzer, true);
sleep_ms(15000); // 15 segundos para pedestres atravessarem
// Desliga os LEDs e buzzer
gpio_put(LED_PEDESTRE_VERDE, 0);
gpio_put(LED_VERMELHO, 0);
pwm_set_enabled(slice_buzzer, false);
pedestre_esperando = false; // Reseta a flag
}
// (6) Controla o ciclo automático do semáforo
void executar_ciclo_semaforo() {
// (A) Fase verde para carros
gpio_put(LED_CARRO_VERDE, 1);
gpio_put(LED_AMARELO, 0);
gpio_put(LED_VERMELHO, 0);
for (int i = 0; i < 80; i++) { // 8 segundos (80 x 100ms)
sleep_ms(100);
if (pedestre_esperando) {
gpio_put(LED_CARRO_VERDE, 0);
gpio_put(LED_AMARELO, 1);
sleep_ms(5000); // Amarelo por 5 segundos
ativar_sistema_pedestre();
return;
}
}
gpio_put(LED_CARRO_VERDE, 0);
// (B) Fase amarela
gpio_put(LED_AMARELO, 1);
for (int i = 0; i < 20; i++) { // 2 segundos (20 x 100ms)
sleep_ms(100);
if (pedestre_esperando) {
// Prolonga o amarelo por mais 3 segundos caso o pedestre
// acione o botão (para ter um ciclo total de 5 segundos)
sleep_ms(3000);
gpio_put(LED_AMARELO, 0);
ativar_sistema_pedestre();
return;
}
}
gpio_put(LED_AMARELO, 0);
// (C) Fase vermelha para carros
gpio_put(LED_VERMELHO, 1);
for (int i = 0; i < 100; i++) { // 10 segundos (100 x 100ms)
sleep_ms(100);
if (pedestre_esperando) {
ativar_sistema_pedestre();
return;
}
}
gpio_put(LED_VERMELHO, 0);
}
////////////////////////////////////////////////////////
// FUNÇÃO PRINCIPAL
////////////////////////////////////////////////////////
int main() {
stdio_init_all();
// Inicializa os componentes
inicializar_pwm_buzzer(BUZZER);
inicializar_botao(BOTAO_PEDESTRE);
inicializar_led(LED_PEDESTRE_VERDE);
inicializar_led(LED_CARRO_VERDE);
inicializar_led(LED_AMARELO);
inicializar_led(LED_VERMELHO);
// Configura a interrupção do botão
gpio_set_irq_enabled_with_callback(BOTAO_PEDESTRE, GPIO_IRQ_EDGE_RISE, true, &botao_pedestre_callback);
while (true) {
executar_ciclo_semaforo(); // Executa o ciclo do semáforo continuamente
}
return 0;
}