FireBeetle 2 ESP32 C6开发板 PWM应用
[复制链接]
在Arduino UNO控制器中,调用analogWrite()函数输出PWM 来控制LED的亮度, 或者控制电机的转速.,在ESP32 C6 Arduino并没有直接实现analogWrite()函数,而且ESP32的PWM更加复杂,Arduino提供的接口并不满足控制PWM的需求。ESP32提供了LEDC(LED Control)库来管理PWM信号,这允许更高级的控制,包括更高的分辨率和多个通道的并发使用。
下面我们来看下ESP32 在Arduino的代码
void analogWrite(uint8_t pin, int value) {
// Use ledc hardware for internal pins
if (pin < SOC_GPIO_PIN_COUNT) {
ledc_channel_handle_t *bus = (ledc_channel_handle_t*)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC);
if(bus == NULL && perimanClearPinBus(pin)){
if(ledcAttach(pin, analog_frequency, analog_resolution) == 0){
log_e("analogWrite setup failed (freq = %u, resolution = %u). Try setting different resolution or frequency");
return;
}
}
ledcWrite(pin, value);
}
}
我们发现ESP三二对arduino的PWM接口做了适配
函数前面定义了两个变量
static uint8_t analog_resolution = 8;
static int analog_frequency = 1000;
所以使用analogWrite()会产生一个1K HZ 8bit分辨率的PWM
ledcWrite() 函数并不是直接接受一个GPIO引脚号(pin )作为参数,而是接受一个LEDC通道号(channel)和一个值(value )。这是因为ESP32的LEDC(LED Control)库使用通道的概念来管理PWM信号,而不是直接绑定到特定的GPIO引脚。
函数原型如下:
bool ledcWrite(uint8_t pin, uint32_t duty)
- pin:PWM输出引脚
- duty:PWM的占空比值,它的范围取决于函数中设置的分辨率(resolution)。
在这些设备中,IO MUX用于将GPIO(通用输入输出)引脚配置为不同的功能,如PWM输出、I2C通信、UART串行通信等。
IO MUX通常用于将GPIO引脚配置为不同的功能;
ledcWrite()的 Pin 可能可以设置为任意数字IO
void analogWriteFrequency(uint8_t pin, uint32_t freq) {
if (ledcChangeFrequency(pin, freq, analog_resolution) == 0){
log_e("analogWrite frequency cant be set due to selected resolution! Try to adjust resolution first");
return;
}
analog_frequency = freq;
}
默认PWM分辨率8 bit
改变给定引脚的频率
void analogWriteResolution(uint8_t pin, uint8_t resolution) {
if (ledcChangeFrequency(pin, analog_frequency, resolution) == 0){
log_e("analogWrite resolution cant be set due to selected frequency! Try to adjust frequency first");
return;
}
analog_resolution = resolution;
}
改变给定引脚的PWM分辨率
代码测试
void setup() {
analogWriteFrequency(D2,10000);
analogWriteFrequency(D13,10000);
analogWrite(D2,25);
analogWrite(D13,100);
}
void loop() {
}
和设置不符合
void setup() {
analogWrite(D2,25);
analogWrite(D13,100);
analogWriteFrequency(D2,10000);
analogWriteFrequency(D13,10000);
}
void loop() {
}
符合设计
@brief 为给定的LEDC引脚设置输出信号的反转。","marks":[]}]}],"state":{"index":1}},{"type":"block","id":"IciE-1715321995887","name":"list-item","data":{"listId":"DS8H-1715321995894","listLevel":1,"listType":"unordered","style":{},"version":1},"nodes":[{"type":"text","id":"69OR-1715321995886","leaves":[{"text":"@param pin GPIO引脚","marks":[]}]}],"state":{"index":2}},{"type":"block","id":"3KPs-1715321995889","name":"list-item","data":{"listId":"DS8H-1715321995894","listLevel":1,"listType":"unordered","style":{},"version":1},"nodes":[{"type":"text","id":"QU50-1715321995888","leaves":[{"text":"@param out_invert 选择是否反转输出(true = 输出反转)。","marks":[]}]}],"state":{"index":3}},{"type":"block","id":"BktE-1715321995893","name":"list-item","data":{"listId":"DS8H-1715321995894","listLevel":1,"listType":"unordered","style":{},"version":1},"nodes":[{"type":"text","id":"k8yX-1715321995892","leaves":[{"text":"@return 如果成功设置了输出反转,返回true;否则返回false。","marks":[]}]}],"state":{"index":4}},{"type":"block","id":"3lLD-1715322029971","name":"paragraph","data":{},"nodes":[{"type":"text","id":"KabB-1715322029970","leaves":[{"text":"**/","marks":[]}]}],"state":{"index":5}},{"type":"block","id":"yLyA-1715321639881","name":"paragraph","data":{"style":{}},"nodes":[{"type":"text","id":"qSfU-1715321639879","leaves":[{"text":"bool ledcOutputInvert(uint8_t pin, bool out_invert);","marks":[]}]}],"state":{}}]">
/**
- @brief 为给定的LEDC引脚设置输出信号的反转。
- @param pin GPIO引脚
- @param out_invert 选择是否反转输出(true = 输出反转)。
- @return 如果成功设置了输出反转,返回true;否则返回false。
**/
bool ledcOutputInvert(uint8_t pin, bool out_invert);
void setup() {
analogWrite(D2,25);
analogWrite(D13,100);
analogWriteFrequency(D2,10000);
analogWriteFrequency(D13,10000);
ledcOutputInvert(D2,true);
}
void loop() {
}
总结:
虽然可以通过Arduino输出PWM,但是接口并不完善,使用者最好还是要使用LEDC(LED Control)库来开发
|