#include <stdio.h>
#include "hardware/pwm.h"
#include "pico/stdlib.h"
#include "hardware/clocks.h"
#include "hardware/timer.h"
// Definição dos pinos dos LEDs
const uint LED_R = 18; // Pino do LED vermelho
const uint LED_G = 19; // Pino do LED verde
const uint LED_B = 20; // Pino do LED azul
// 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;
volatile float blue_duty_cycle;
// Variáveis para armazenar o status dos LEDs (0 = inativo, 1 = ativo)
volatile bool red_led_active = true;
volatile bool blue_led_active = true;
volatile bool green_led_active = false;
// 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);
uint channel = pwm_gpio_to_channel(led);
uint16_t level = (uint16_t)((duty_cycle / 100.0f) * PWM_TOP);
pwm_set_chan_level(slice, channel, level);
if (led == LED_R) red_led_active = true;
if (led == LED_B) blue_led_active = true;
}
// 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;
if (red_duty_cycle > DUTY_CYCLE_MAX) {
red_duty_cycle = DUTY_CYCLE_MIN;
}
set_pwm_duty_cycle(LED_R, red_duty_cycle);
printf("Red Duty Cycle (GPIO %d) = %.2f\n", LED_R, red_duty_cycle);
// Atualiza o duty cycle do LED azul
blue_duty_cycle += DUTY_CYCLE_STEP;
if (blue_duty_cycle > DUTY_CYCLE_MAX) {
blue_duty_cycle = DUTY_CYCLE_MIN;
}
set_pwm_duty_cycle(LED_B, blue_duty_cycle);
printf("Blue Duty Cycle (GPIO %d) = %.2f\n", LED_B, blue_duty_cycle);
return true;
}
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);
setup_pwm_led(LED_B, PWM_FREQ_BLUE);
// Inicializa os duty cycles dos LEDs
red_duty_cycle = DUTY_CYCLE_MIN;
set_pwm_duty_cycle(LED_R, red_duty_cycle);
blue_duty_cycle = DUTY_CYCLE_MIN;
set_pwm_duty_cycle(LED_B, blue_duty_cycle);
// 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);
gpio_set_dir(LED_G, GPIO_OUT);
gpio_put(LED_G, false);
printf("LED Vermelho (GPIO %d) Ativo = %s\n", LED_R, red_led_active ? "true" : "false" );
printf("LED Verde (GPIO %d) Ativo = %s\n", LED_G, green_led_active ? "true" : "false" );
printf("LED Azul (GPIO %d) Ativo = %s\n", LED_B, blue_led_active ? "true" : "false" );
while (true) {
sleep_ms(10);
}
return 0;
}