#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/irq.h"
// Definições para os LEDs RGB
const uint LED_RED = 12; // Pino para o LED vermelho
const uint LED_GREEN = 14; // Pino para o LED verde
const uint LED_BLUE = 13; // Pino para o LED azul
// Configurações do PWM
const uint16_t PERIOD_RED = 5000; // Período para o LED vermelho (0.2 kHz)
const uint16_t PERIOD_GREEN = 1000; // Período para o LED verde (1 kHz)
const uint16_t PERIOD_BLUE = 500; // Período para o LED azul (2 kHz)
// Incremento do duty cycle
const uint8_t DUTY_INCREMENT = 2; // Incremento de 2% para mudanças mais graduais
// Duty cycle inicial
volatile uint16_t duty_red = 5;
volatile uint16_t duty_green = 5;
volatile uint16_t duty_blue = 5;
// Função para configurar o PWM
void setup_pwm(uint pin, uint16_t period, float divider) {
gpio_set_function(pin, GPIO_FUNC_PWM); // Configura o pino para função PWM
uint slice = pwm_gpio_to_slice_num(pin); // Obtém o slice do pino
pwm_set_clkdiv(slice, divider); // Define o divisor de clock
pwm_set_wrap(slice, period); // Define o período do PWM
pwm_set_gpio_level(pin, 0); // Inicializa o nível do PWM com duty cycle 0%
pwm_set_enabled(slice, true); // Ativa o PWM
}
// Função de interrupção para atualizar os duty cycles
void pwm_irq_handler() {
// Atualiza o duty cycle do LED vermelho
duty_red += DUTY_INCREMENT;
if (duty_red > 100) duty_red = 5; // Retorna ao valor mínimo
pwm_set_gpio_level(LED_RED, (duty_red * PERIOD_RED) / 100);
// Atualiza o duty cycle do LED verde
duty_green += DUTY_INCREMENT;
if (duty_green > 100) duty_green = 5; // Retorna ao valor mínimo
pwm_set_gpio_level(LED_GREEN, (duty_green * PERIOD_GREEN) / 100);
// Atualiza o duty cycle do LED azul
duty_blue += DUTY_INCREMENT;
if (duty_blue > 100) duty_blue = 5; // Retorna ao valor mínimo
pwm_set_gpio_level(LED_BLUE, (duty_blue * PERIOD_BLUE) / 100);
// Limpa a interrupção
pwm_clear_irq(pwm_gpio_to_slice_num(LED_RED));
}
int main() {
stdio_init_all();
// Configura os LEDs
setup_pwm(LED_RED, PERIOD_RED, 64.0);
setup_pwm(LED_GREEN, PERIOD_GREEN, 64.0);
setup_pwm(LED_BLUE, PERIOD_BLUE, 64.0);
// Configura a interrupção no slice do LED vermelho
uint slice_red = pwm_gpio_to_slice_num(LED_RED);
pwm_clear_irq(slice_red);
pwm_set_irq_enabled(slice_red, true);
irq_set_exclusive_handler(PWM_IRQ_WRAP, pwm_irq_handler);
irq_set_enabled(PWM_IRQ_WRAP, true);
// Loop principal (não faz nada, o trabalho é feito na interrupção)
while (true) {
tight_loop_contents(); // Aguarda interrupções
}
}