MCPWM
ESP32 有两个 MCPWM 单元,可用于控制不同类型的电机。每个单元都有三对PWM输出。
![](https://img-blog.csdnimg.cn/img_convert/343273daf70ff581b72b772b935c7855.png)
MCPWM 装置的更详细框图如下所示。每个 A/B 对可由三个定时器定时器 0、1 和 2 中的任何一个计时。同一定时器可用于为多对PWM输出提供时钟。每个单元还能够收集输入,例如,检测电机过电流或过电压,以及获得例如转子位置的反馈。
![](https://img-blog.csdnimg.cn/img_convert/46768ec4b9c7be0ba9a071e07c840cd1.png)
此 API 的说明从配置 MCPWM 的定时器和发电机子模块开始,以提供基本的电机控制功能。然后讨论故障处理程序、信号捕获、载波和中断的更高级子模块和功能。
小智学长桌面屏幕初始化ds_pwm_init();所用到mcpwm的代码
这个代码用作于控制蜂鸣器。
![](https://img-blog.csdnimg.cn/img_convert/f25d888df42bba33b88c7e1e1a90bd7d.png)
(非常重要)思路:
第一步 mcpwm_gpio_init
void ds_pwm_init(void)
{
mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM1A, SERVO_PULSE_GPIO);
![](https://img-blog.csdnimg.cn/img_convert/1a638d027e8d2ab7791a930c23df9987.png)
第二步 mcpwm_init
mcpwm_config_t pwm_config = {
.frequency = 4000, // 频率= 50Hz,即每个伺服电机的时间周期应为20ms
.cmpr_a = 0, // PWMxA占空比为0
.counter_mode = MCPWM_UP_COUNTER,//用于非对称 MCPWM
.duty_mode = MCPWM_DUTY_MODE_0,//有源高占空比,即非对称 MCPWM 的占空比与高时间成正比
};
mcpwm_init(MCPWM_UNIT_1, MCPWM_TIMER_1, &pwm_config);
![](https://img-blog.csdnimg.cn/img_convert/41e747294461bb7a2d70d9fee406c85b.png)
第三步 ds_beep_stop();
static void ds_beep_stop(){
//设置MCPWM的某个generator信号为高[或低]
// mcpwm_set_signal_high(MCPWM_UNIT_1, MCPWM_TIMER_1, MCPWM_GEN_A);
mcpwm_set_signal_low(MCPWM_UNIT_1, MCPWM_TIMER_1, MCPWM_GEN_A);
}
![](https://img-blog.csdnimg.cn/img_convert/619923157a7a20fed97270a680e30305.png)
第四步 ds_beep_start();
static void ds_beep_start(){
//设置占空比
mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_1,MCPWM_GEN_A,50);
//设置占空比类型,并恢复PWM输出
mcpwm_set_duty_type(MCPWM_UNIT_1, MCPWM_TIMER_1,MCPWM_GEN_A,MCPWM_DUTY_MODE_0);
}
![](https://img-blog.csdnimg.cn/img_convert/1dea9ac1349cdfdc39cb3c429d1ee64f.png)
第五步 队列传递
![](https://img-blog.csdnimg.cn/img_convert/81946eafd5f85e4f320e78ec840bcad0.png)
beep_queue = xQueueCreate(10, sizeof(uint32_t));//创建队列
xTaskCreate(beep_task, "beep_task", 1024, NULL, 10, NULL);//创建任务
static void beep_task(void* arg)//这个任务用于接收队列中的事件,判断蜂鸣器叫声时间长短
{
uint32_t evt;
for(;;) {
if(xQueueReceive(beep_queue, &evt, portMAX_DELAY)) {
if(evt == BEEP_SHORT_100MS){
ds_beep_start();
vTaskDelay(100 / portTICK_PERIOD_MS);
ds_beep_stop();
}else if(evt == BEEP_SHORT_500MS){
ds_beep_start();
vTaskDelay(100 / portTICK_PERIOD_MS);
ds_beep_stop();
vTaskDelay(100 / portTICK_PERIOD_MS);
ds_beep_start();
vTaskDelay(100 / portTICK_PERIOD_MS);
ds_beep_stop();
}else if(evt == BEEP_LONG){
ds_beep_start();
vTaskDelay(100 / portTICK_PERIOD_MS);
ds_beep_stop();
vTaskDelay(100 / portTICK_PERIOD_MS);
ds_beep_start();
vTaskDelay(100 / portTICK_PERIOD_MS);
ds_beep_stop();
vTaskDelay(100 / portTICK_PERIOD_MS);
ds_beep_start();
vTaskDelay(100 / portTICK_PERIOD_MS);
ds_beep_stop();
}
}
}
}
void send_beep_event(BEEP_TYPE_E type){//触发蜂鸣器发送队列任务
uint32_t evt = type;
xQueueSend(beep_queue, &evt, 0);
}
void send_beep_event_from_isr(BEEP_TYPE_E type){
uint32_t evt = type;
xQueueSendFromISR(beep_queue, &evt, 0);
}