Programming The ESP32 In C - PWM First Example |
Written by Harry Fairhead | ||||||
Wednesday, 05 February 2025 | ||||||
Page 5 of 5
Changing the PWMThere are a great many functions which can be used to change the operation of the PWM hardware after it has been configured. The first acts on the channel.
There are three that act on the timer:
You can also change the clock divider, duty resolution and the choice of clock using:
duty_resolution, clk_src) To work with the PWM’s frequency you can use:
In most cases it is the duty cycle of the PWM output you need to change and this can be done with the help of the following functions:
The set_duty function doesn’t actually change the duty cycle; we need to call update_duty to enforce the change which happens at the next timer restart. If you want to change the hpoint you can use:
The functions to update the duty cycle are not threadsafe and should not be used in different tasks at the same time. For concurrent tasks use the alternative threadsafe function:
As an example of changing the duty cycle, this small function changes it in terms of a percentage: void changeDutyLow(int chan, int res, float duty) {
ledc_set_duty(LEDC_LOW_SPEED_MODE, chan,
((float)(2 << (res - 1))) * duty);
ledc_update_duty(LEDC_LOW_SPEED_MODE, chan);
}
For example to use this to modulate the duty cycle: #include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "esp_rom_sys.h"
#include "driver/ledc.h"
#include <unistd.h>
void delay_us(int t) {
usleep(t);
}
void PWMconfigLow(int gpio, int chan, int timer, int res,
int freq, float duty) {
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.clk_cfg = LEDC_APB_CLK
};
ledc_timer.timer_num = timer;
ledc_timer.duty_resolution = res;
ledc_timer.freq_hz = freq;
ledc_channel_config_t ledc_channel = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.hpoint = 0,
.intr_type = LEDC_INTR_DISABLE,
};
ledc_channel.channel = chan;
ledc_channel.timer_sel = timer;
ledc_channel.gpio_num = gpio;
ledc_channel.duty = ((float)(2 << (res - 1))) * duty;
ledc_timer_config(&ledc_timer);
ledc_channel_config(&ledc_channel);
}
void changeDutyLow(int chan, int res, float duty) {
ledc_set_duty(LEDC_LOW_SPEED_MODE, chan,
((float)(2 << (res - 1))) * duty);
ledc_update_duty(LEDC_LOW_SPEED_MODE, chan);
}
void app_main(void)
{
PWMconfigLow(2, 0, 3, 13, 4000, 0.25);
while (true) {
delay_us(1000);
changeDutyLow(0, 13,0.5);
delay_us(1000);
changeDutyLow(0, 13,0.25);
}
}
There are two functions which can be used to change the configuration of the channel:
Notice that this adds the new pin to the pin selected during the setup and that you can have the same PWM signal on more than one GPIO line. In chapter but not in this extract
Summary
Programming The ESP32 In C
|
||||||
Last Updated ( Wednesday, 05 February 2025 ) |