diff --git a/lab_4/lab_4.c b/lab_4/lab_4.c index 07a265b..7884746 100644 --- a/lab_4/lab_4.c +++ b/lab_4/lab_4.c @@ -15,8 +15,6 @@ #include "hardware/adc.h" #define PWM_PIN 2 -#define PWM_FREQ 20 -#define PWM_DUTY 50 #define ADC_PIN 26 #define ADC_FREQ 25 @@ -41,48 +39,6 @@ bool repeating_timer_callback (struct repeating_timer *t) { return true; } -/** - * Helper function to calculate the clock divider and wrap value for PWM - * Based on: https://www.i-programmer.info/programming/hardware/14849-the-pico-in-c-basic-pwm.html - * - * RP2040 clock is 125 MHz, PWM Counter is 16-bit - * Clock divider is 16-bit, with 12-bit integer and 4-bit fraction - * @param slice_num PWM slice number - * @param channel PWM channel - * @param frequency PWM frequency - * @param duty_cycle PWM duty cycle - * @return PWM wrap value - */ -uint32_t pwm_set_freq_duty (uint slice_num, - uint channel, uint32_t frequency, int duty_cycle) { - uint32_t clock = 125000000; - - // divider = Ceil(16 * clock / 65536 * frequency) + remainder - // = Ceil(clock / frequency / 4096) + remainder - uint32_t divider16 = clock / frequency / 4096 + - (clock % (frequency * 4096) != - 0); // Round up if less than 1 - - // If divider is less than 16, set it to 16 (16-bit counter) - if (divider16 / 16 == 0) - { - divider16 = 16; - } - - // Wrap value is 16 bits, so max value is 65535 (2^16 - 1) - uint32_t wrap = clock * 16 / divider16 / frequency - 1; - - // Set clock divider and wrap value - pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, - divider16 & 0xF); - pwm_set_wrap(slice_num, wrap); - - // Level = wrap * duty_cycle(as fraction) - // = wrap * duty_cycle / 100 - pwm_set_chan_level(slice_num, channel, wrap * duty_cycle / 100); - return wrap; -} - /** * Setup Function for PWM and ADC * @param timer Repeating timer for ADC @@ -92,7 +48,11 @@ void setup (struct repeating_timer *timer) { gpio_set_function(PWM_PIN, GPIO_FUNC_PWM); uint slice_num = pwm_gpio_to_slice_num(PWM_PIN); uint channel = pwm_gpio_to_channel(PWM_PIN); - pwm_set_freq_duty(slice_num, channel, PWM_FREQ, PWM_DUTY); + + pwm_set_clkdiv(slice_num, 100); // 125 MHz / 100 = 1.25 MHz + pwm_set_wrap(slice_num, 62500); // 1.25 MHz / 62500 = 20 Hz + pwm_set_chan_level(slice_num, channel, 62500/2); // 50% duty cycle + pwm_set_enabled(slice_num, true); // ADC setup