概述
每个MCPWM 外设都连接来自GPIO 矩阵的3 个故障信号(FAULT0,FAULT1 和FAULT2)。这些信号用于指示
外部故障状况,并且可由故障检测模块预处理后生成故障事件。
在检测到故障时强制PWMxA/B输出固定信号,并能支持一次性跳闸模式(OST)和周期跳闸模式(CBC):
- OST模式时: 故障解除时仍保持PWMxA/B输出保护状态
- CBC模式时: 故障解除时恢复PWMxA/B故障前输出状态
关键函数说明
//初始化故障处理模块
ESP_ERROR_CHECK(mcpwm_fault_init(
MCPWM_UNIT_0, // MCPWM_UNIT_0 / MCPWM_UNIT_1
MCPWM_LOW_LEVEL_TGR, // MCPWM_HIGH_LEVEL_TGR / MCPWM_LOW_LEVEL_TGR
MCPWM_SELECT_F0)); // MCPWM_SELECT_F0 / MCPWM_SELECT_F1 / MCPWM_SELECT_F2
//设置单次跳闸模式(OST)
ESP_ERROR_CHECK(mcpwm_fault_set_oneshot_mode(
MCPWM_UNIT_0, // MCPWM_UNIT_0 / MCPWM_UNIT_1
MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2
MCPWM_SELECT_F0, // MCPWM_SELECT_F0 / MCPWM_SELECT_F1 / MCPWM_SELECT_F2
MCPWM_ACTION_FORCE_LOW, // PWMxA动作: MCPWM_ACTION_NO_CHANGE / MCPWM_ACTION_FORCE_LOW/HIGH / MCPWM_ACTION_TOGGLE
MCPWM_ACTION_FORCE_LOW)); // PWMxB动作: MCPWM_ACTION_NO_CHANGE / MCPWM_ACTION_FORCE_LOW/HIGH / MCPWM_ACTION_TOGGLE
//设置周期跳闸模式(CBC)
ESP_ERROR_CHECK(mcpwm_fault_set_cyc_mode(
MCPWM_UNIT_0, // MCPWM_UNIT_0 / MCPWM_UNIT_1
MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2
MCPWM_SELECT_F0, // MCPWM_SELECT_F0 / MCPWM_SELECT_F1 / MCPWM_SELECT_F2
MCPWM_ACTION_FORCE_LOW, // PWMxA动作: MCPWM_ACTION_NO_CHANGE / MCPWM_ACTION_FORCE_LOW/HIGH / MCPWM_ACTION_TOGGLE
MCPWM_ACTION_FORCE_LOW)); // PWMxB动作: MCPWM_ACTION_NO_CHANGE / MCPWM_ACTION_FORCE_LOW/HIGH / MCPWM_ACTION_TOGGLE
示例代码
该程序采用外部IO4模拟故障信号,硬件上连接IO4和IO5输入故障信号,PWM启动后每5s输出一次50ms的故障信号。
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "string.h"
#include "driver/mcpwm.h"
#include "driver/gpio.h"
#include "soc/mcpwm_struct.h"
#define io_num(x) x
void app_main(void)
{
ESP_ERROR_CHECK(gpio_reset_pin(io_num(4)));
ESP_ERROR_CHECK(gpio_set_direction(io_num(4), GPIO_MODE_OUTPUT));
ESP_ERROR_CHECK(gpio_set_level(io_num(4), 1));
// mcepwm IO配置
mcpwm_pin_config_t mcpwm_pin = {
.mcpwm0a_out_num = io_num(14), //实际IO号
.mcpwm0b_out_num = io_num(15),
.mcpwm1a_out_num = -1,
.mcpwm1b_out_num = -1,
.mcpwm2a_out_num = -1,
.mcpwm2b_out_num = -1,
.mcpwm_cap0_in_num = -1,
.mcpwm_cap1_in_num = -1,
.mcpwm_cap2_in_num = -1,
.mcpwm_sync0_in_num = -1, // Not used
.mcpwm_sync1_in_num = -1, // Not used
.mcpwm_sync2_in_num = -1, // Not used
.mcpwm_fault0_in_num = io_num(5),
.mcpwm_fault1_in_num = -1, // Not used
.mcpwm_fault2_in_num = -1 // Not used
};
ESP_ERROR_CHECK(mcpwm_set_pin(MCPWM_UNIT_0, &mcpwm_pin));
//设置PWM定时器分辨率
ESP_ERROR_CHECK(mcpwm_group_set_resolution(MCPWM_UNIT_0, 10000000)); // MCPWM号(0/1)、分辨率(默认:10,000,000)
ESP_ERROR_CHECK(mcpwm_timer_set_resolution(MCPWM_UNIT_0, MCPWM_TIMER_0, 1000000)); //定时器号(0/1/2)、分辨率(默认:1,000,000)
mcpwm_config_t mcpwm_conf = {
.frequency = 100, //输出pwm波形频率 Hz
.cmpr_a = 30, //操作器A输出占空比, i.e duty_a = 62.3
.cmpr_b = 50, //操作器B输出占空比, i.e duty_a = 42.8
/*******************************************
*duty_mode (占空比类型):
* MCPWM_DUTY_MODE_0: 高有效,例如:%20占空比 == 高电平20%
* MCPWM_DUTY_MODE_1: 低有效,例如:%20占空比 == 低电平20%
* MCPWM_HAL_GENERATOR_MODE_FORCE_LOW: 输出强制为低
* MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH:输出强制为高
* MCPWM_DUTY_MODE_MAX:Num of duty cycle modes
********************************************/
.duty_mode = MCPWM_DUTY_MODE_0,
/****************************************
* counter_mode (计数模式):
* MCPWM_FREEZE_COUNTER: 计数器冻结
* MCPWM_UP_COUNTER: 计数器递增,左对齐,频率不变
* MCPWM_DOWN_COUNTER: 计数器递减,右对齐,频率不变
* MCPWM_UP_DOWN_COUNTER:计数器递增递减,中间对齐,频率减半
********************************************/
.counter_mode = MCPWM_UP_COUNTER};
ESP_ERROR_CHECK(mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &mcpwm_conf)); //启动定时器0
ESP_ERROR_CHECK(mcpwm_fault_init(
MCPWM_UNIT_0, // MCPWM_UNIT_0 / MCPWM_UNIT_1
MCPWM_LOW_LEVEL_TGR, // MCPWM_HIGH_LEVEL_TGR / MCPWM_LOW_LEVEL_TGR
MCPWM_SELECT_F0)); // MCPWM_SELECT_F0 / MCPWM_SELECT_F1 / MCPWM_SELECT_F2
//ESP_ERROR_CHECK(mcpwm_fault_set_oneshot_mode(
// MCPWM_UNIT_0, // MCPWM_UNIT_0 / MCPWM_UNIT_1
// MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2
// MCPWM_SELECT_F0, // MCPWM_SELECT_F0 / MCPWM_SELECT_F1 / MCPWM_SELECT_F2
// MCPWM_ACTION_FORCE_LOW, // PWMxA动作: MCPWM_ACTION_NO_CHANGE / MCPWM_ACTION_FORCE_LOW/HIGH / MCPWM_ACTION_TOGGLE
// MCPWM_ACTION_FORCE_LOW)); // PWMxB动作: MCPWM_ACTION_NO_CHANGE / MCPWM_ACTION_FORCE_LOW/HIGH / MCPWM_ACTION_TOGGLE
ESP_ERROR_CHECK(mcpwm_fault_set_cyc_mode(
MCPWM_UNIT_0, // MCPWM_UNIT_0 / MCPWM_UNIT_1
MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2
MCPWM_SELECT_F0, // MCPWM_SELECT_F0 / MCPWM_SELECT_F1 / MCPWM_SELECT_F2
MCPWM_ACTION_FORCE_LOW, // PWMxA动作: MCPWM_ACTION_NO_CHANGE / MCPWM_ACTION_FORCE_LOW/HIGH / MCPWM_ACTION_TOGGLE
MCPWM_ACTION_FORCE_LOW)); // PWMxB动作: MCPWM_ACTION_NO_CHANGE / MCPWM_ACTION_FORCE_LOW/HIGH / MCPWM_ACTION_TOGGLE
// 5s后IO模拟故障
while (1)
{
vTaskDelay(pdMS_TO_TICKS(5000));
ESP_ERROR_CHECK(gpio_set_level(io_num(4), 0));
vTaskDelay(pdMS_TO_TICKS(50));
ESP_ERROR_CHECK(gpio_set_level(io_num(4), 1));
}
}
效果:
一次性跳闸模式(OST):
示波器1和2通道分别为PWM0A和B输出,3通道为同步信号输出。
周期跳闸模式(CBC):