//Antonio Sergio Castro de Carvalho Junior
// ==================================================
// Comentarios necessarios:
// ==================================================
//Comportamento dos LEDs:
//LED Azul (12):
//Acende imediatamente com 75% de brilho fixo
//Sem delay inicial ou efeito de fade
//LED Vermelho (13):
//Inicia com 5% de brilho
//Começa o fade (aumento gradual) após 2 segundos
//Primeira atualização ocorre 2s após a inicialização
// ==================================================
//Sequência Visual Esperada:
// ==================================================
//T = 0s:
//Azul: Ligado (75% de brilho)
//Vermelho: Ligado (5% de brilho - quase IMPERCEPTIVEL)
//T = 2s:
//Vermelho inicia o fade (5% → 10% → 15%...)
//T = 12s:
//Ciclo completo do fade (5% → 100% → 5%)
// Conclusão: Ambos os LEDs são ativados simultaneamente,
//mas o Azul terá brilho total imediatamente, enquanto o
//Vermelho só se tornará visivelmente ativo após os primeiros 2 segundos.
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
// ==================================================
// CONFIGURAÇÕES HARDWARE
// ==================================================
// Pinos dos LEDs
const uint LED_B = 12; // LED Azul (duty cycle fixo)
const uint LED_R = 13; // LED Vermelho (duty cycle variável)
// Parâmetros PWM LED Vermelho (1 kHz)
const uint16_t PERIOD_RED = 12500; // Período para 1 kHz
const float DIVIDER_PWM_RED = 10.0;
const uint16_t LED_STEP = 625; // Incremento de 5%
const uint32_t PWM_REFRESH_LEVEL = 2000; // Atualizações a cada 2s
const uint32_t TRANSITION_TIME = 2000000;// Intervalo entre transições
// Controle do LED Vermelho
uint16_t led_level = LED_STEP; // Nível atual (5%)
uint32_t last_transition_time = 0; // Última mudança
int8_t direction = 1; // Sentido do fade
uint slice_red; // Canal PWM
// Parâmetros PWM LED Azul (10 kHz fixo)
const uint16_t PERIOD_BLUE = 781; // Período para 10 kHz
const float DIVIDER_PWM_BLUE = 16.0;
const uint16_t DUTY_CYCLE_BLUE = 75; // 75% de duty cycle
// ==================================================
// INTERRUPÇÃO PWM (CONTROLE DO LED VERMELHO)
// ==================================================
void pwm_irq_handler() {
static uint32_t count = 0;
uint32_t current_time = time_us_32();
pwm_clear_irq(slice_red);
// Atualiza duty cycle a cada 2 segundos
if (count++ < PWM_REFRESH_LEVEL) return;
count = 0;
if (current_time - last_transition_time < TRANSITION_TIME) return;
last_transition_time = current_time;
// Lógica de fade in/out
led_level += (direction * LED_STEP);
// Inverte direção nos limites
if (led_level >= PERIOD_RED || led_level <= LED_STEP) {
direction *= -1;
led_level = (led_level > PERIOD_RED) ? PERIOD_RED : LED_STEP;
}
// Aplica novo nível e exibe status
pwm_set_gpio_level(LED_R, led_level);
printf("Duty Cycle Vermelho: %.1f%%\n", (led_level * 100.0) / PERIOD_RED);
}
// ==================================================
// INICIALIZAÇÃO DOS PWMs
// ==================================================
void setup_pwm() {
// Configura LED Vermelho
gpio_set_function(LED_R, GPIO_FUNC_PWM);
slice_red = pwm_gpio_to_slice_num(LED_R);
pwm_config config_red = pwm_get_default_config();
pwm_config_set_clkdiv(&config_red, DIVIDER_PWM_RED);
pwm_config_set_wrap(&config_red, PERIOD_RED);
pwm_init(slice_red, &config_red, true);
pwm_set_gpio_level(LED_R, led_level);
// Configura LED Azul
gpio_set_function(LED_B, GPIO_FUNC_PWM);
uint slice_blue = pwm_gpio_to_slice_num(LED_B);
pwm_config config_blue = pwm_get_default_config();
pwm_config_set_clkdiv(&config_blue, DIVIDER_PWM_BLUE);
pwm_config_set_wrap(&config_blue, PERIOD_BLUE);
pwm_init(slice_blue, &config_blue, true);
pwm_set_gpio_level(LED_B, (DUTY_CYCLE_BLUE * PERIOD_BLUE) / 100);
// Habilita interrupções
irq_set_exclusive_handler(PWM_IRQ_WRAP, pwm_irq_handler);
pwm_set_irq_enabled(slice_red, true);
irq_set_enabled(PWM_IRQ_WRAP, true);
}
// ==================================================
// LOOP PRINCIPAL
// ==================================================
int main() {
stdio_init_all(); // Inicia comunicação serial
setup_pwm(); // Configura hardware
while (true) {
sleep_ms(10); // Economiza energia
}
}