#include <stdio.h> // Biblioteca padrão de entrada e saída
#include "hardware/pwm.h" // Biblioteca para controle de PWM no RP2040
#include "pico/stdlib.h" // Biblioteca padrão do Raspberry Pi Pico
#include "hardware/clocks.h"// Biblioteca para funções de clock
#include "hardware/timer.h" // Biblioteca para temporizadores
// Definição dos pinos dos LEDs
const uint LED_G = 11; // Pino do LED verde
const uint LED_B = 12; // Pino do LED azul
const uint LED_R = 13; // Pino do LED vermelho
// Configurações do PWM
const uint PWM_FREQ_RED = 1000; // Frequência do PWM para o LED vermelho (1 kHz)
const uint PWM_FREQ_BLUE = 10000; // Frequência do PWM para o LED azul (10 kHz)
const float PWM_TOP = 100.0f; // Valor máximo do contador PWM (para cálculo do duty cycle)
// Configurações do Duty Cycle
const float DUTY_CYCLE_STEP = 5.0f; // Incremento do duty cycle (5%)
const float DUTY_CYCLE_MIN = 5.0f; // Duty cycle inicial e mínimo (5%)
const float DUTY_CYCLE_MAX = 100.0f; // Duty cycle máximo (100%)
// Variáveis para armazenar os níveis de PWM dos LEDs
volatile float red_duty_cycle; // Duty cycle atual do LED vermelho
volatile float blue_duty_cycle; // Duty cycle atual do LED azul
// Função para configurar o PWM de um LED
void setup_pwm_led(uint led, uint freq) {
gpio_set_function(led, GPIO_FUNC_PWM); // Configura o pino do LED como saída PWM
uint slice = pwm_gpio_to_slice_num(led); // Obtém o slice do PWM associado ao pino do LED
float clock_div = (float)clock_get_hz(clk_sys) / (freq * PWM_TOP); // Calcula o divisor de clock
pwm_set_clkdiv(slice, clock_div); // Define o divisor de clock do PWM
pwm_set_wrap(slice, (uint16_t)PWM_TOP); // Define o período do PWM
pwm_set_enabled(slice, true); // Habilita o PWM
}
// Função para definir o duty cycle de um LED
void set_pwm_duty_cycle(uint led, float duty_cycle) {
uint slice = pwm_gpio_to_slice_num(led); // Obtém o slice do PWM associado ao pino do LED
uint channel = pwm_gpio_to_channel(led); // Obtém o canal do PWM associado ao pino do LED
uint16_t level = (uint16_t)((duty_cycle / 100.0f) * PWM_TOP); // Calcula o nível PWM com base no duty cycle
pwm_set_chan_level(slice, channel, level); // Define o nível de PWM
}
// Função de callback do timer para atualizar o duty cycle
bool repeating_timer_callback(struct repeating_timer *t) {
// Atualiza o duty cycle do LED vermelho
red_duty_cycle += DUTY_CYCLE_STEP; // Incrementa o duty cycle
if (red_duty_cycle > DUTY_CYCLE_MAX) { // Verifica se o duty cycle atingiu o máximo
red_duty_cycle = DUTY_CYCLE_MIN; // Reseta para o valor mínimo
}
set_pwm_duty_cycle(LED_R, red_duty_cycle); // Define o nível PWM do LED vermelho
printf("Red Duty Cycle: %.2f\n", red_duty_cycle); // Imprime o duty cycle atual
// Atualiza o duty cycle do LED azul
blue_duty_cycle += DUTY_CYCLE_STEP; // Incrementa o duty cycle
if (blue_duty_cycle > DUTY_CYCLE_MAX) { // Verifica se o duty cycle atingiu o máximo
blue_duty_cycle = DUTY_CYCLE_MIN; // Reseta para o valor mínimo
}
set_pwm_duty_cycle(LED_B, blue_duty_cycle); // Define o nível PWM do LED azul
printf("Blue Duty Cycle: %.2f\n", blue_duty_cycle); // Imprime o duty cycle atual
return true; // Mantém o timer ativo
}
int main() {
stdio_init_all(); // Inicializa a comunicação serial
printf("Iniciando Sistema com PWM!\n"); // Mensagem inicial
// Configura o PWM para os LEDs vermelho e azul
setup_pwm_led(LED_R, PWM_FREQ_RED); // Configura o PWM para o LED vermelho
setup_pwm_led(LED_B, PWM_FREQ_BLUE); // Configura o PWM para o LED azul
// Inicializa os duty cycles dos LEDs
red_duty_cycle = DUTY_CYCLE_MIN; // Define o duty cycle inicial do LED vermelho
set_pwm_duty_cycle(LED_R, red_duty_cycle); // Define o duty cycle inicial do LED vermelho
blue_duty_cycle = DUTY_CYCLE_MIN; // Define o duty cycle inicial do LED azul
set_pwm_duty_cycle(LED_B, blue_duty_cycle); // Define o duty cycle inicial do LED azul
// Configura o temporizador com interrupções
struct repeating_timer timer;
add_repeating_timer_ms(2000, repeating_timer_callback, NULL, &timer);
// Mantém o LED verde inativo
gpio_init(LED_G); // Inicializa o pino do LED verde
gpio_set_dir(LED_G, GPIO_OUT); // Define o pino do LED verde como saída
gpio_put(LED_G, false); // Desliga o LED verde
while (true) {
sleep_ms(10); // Mantém o programa em execução sem uso excessivo da CPU
}
return 0;
}