esp32外设使用-MCPWM载波模块使用
- 概述
- 关键函数说明
- 示例程序
概述
载波模块主要用在PWM输出信号与驱动器之间通过变压器隔离的应用,使用高频载波对PWM进行调制输出。如下图所示的波形,第一个脉冲宽度可单独配置,目的在于提供高能量脉冲以接通电源开关;随后的脉冲可整体调整频率和占空比,用于保持上电的状态。
关键函数说明
注意载波配置需在mcpwm_init()函数之后,否则载波无输出。
//载波模块配置
mcpwm_carrier_config_t car_cfg = {
.carrier_period = 1, // 载波周期:1-16; 载波周期 = (carrier_period + 1)*800ns
.carrier_duty = 1, // 载波占空比:1-8; 载波占空比 = carrier_duty * 12.5%
.pulse_width_in_os = 1, //第一个脉冲宽度 1-16; 第一个脉冲宽度 = (载波周期)*(pulse_width_in_os + 1)
.carrier_os_mode = MCPWM_ONESHOT_MODE_EN, //开启/关闭第一个脉冲设置:MCPWM_ONESHOT_MODE_EN / MCPWM_ONESHOT_MODE_DIS
.carrier_ivt_mode = MCPWM_CARRIER_OUT_IVT_DIS //输出载波是否反相:MCPWM_CARRIER_OUT_IVT_EN / MCPWM_CARRIER_OUT_IVT_DIS
};
//初始化载波模块
ESP_ERROR_CHECK(mcpwm_carrier_init(
MCPWM_UNIT_0, // MCPWM_UNIT_0/1
MCPWM_TIMER_0, // MCPWM_TIMER_0/1/2
&car_cfg));
//启动载波输出
ESP_ERROR_CHECK(mcpwm_carrier_enable(
MCPWM_UNIT_0, // MCPWM_UNIT_0/1
MCPWM_TIMER_0)); // MCPWM_TIMER_0/1/2
//关闭载波输出
esp_err_t mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
//设置载波周期
esp_err_t mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_period)
//设置载波占空比
esp_err_t mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_duty)
//开启第一个脉冲配置
esp_err_t mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t pulse_width)
//关闭第一个脉冲配置
esp_err_t mcpwm_carrier_oneshot_mode_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
//载波输出反相设置
esp_err_t mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_carrier_out_ivt_t carrier_ivt_mode)
示例程序
该程序对输出100Hz占空比为30%的PWM波进行调制输出,配置载波周期为1600ns,载波占空比为12.5%,载波第一个脉冲宽度为3200ns。
#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"
#define io_num(x) x
void app_main(void)
{
// mcpwm 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 = -1,
.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 = 0, //操作器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
//载波模块配置
mcpwm_carrier_config_t car_cfg = {
.carrier_period = 1, // 载波周期:1-16; 载波周期 = (carrier_period + 1)*800ns
.carrier_duty = 1, // 载波占空比:1-8; 载波占空比 = carrier_duty * 12.5%
.pulse_width_in_os = 1, //第一个脉冲宽度 1-16; 第一个脉冲宽度 = (载波周期)*(pulse_width_in_os + 1)
.carrier_os_mode = MCPWM_ONESHOT_MODE_EN, //开启/关闭第一个脉冲设置:MCPWM_ONESHOT_MODE_EN / MCPWM_ONESHOT_MODE_DIS
.carrier_ivt_mode = MCPWM_CARRIER_OUT_IVT_DIS //输出载波是否反相:MCPWM_CARRIER_OUT_IVT_EN / MCPWM_CARRIER_OUT_IVT_DIS
};
ESP_ERROR_CHECK(mcpwm_carrier_init(
MCPWM_UNIT_0, // MCPWM_UNIT_0/1
MCPWM_TIMER_0, // MCPWM_TIMER_0/1/2
&car_cfg));
ESP_ERROR_CHECK(mcpwm_carrier_enable(
MCPWM_UNIT_0, // MCPWM_UNIT_0/1
MCPWM_TIMER_0)); // MCPWM_TIMER_0/1/2
}
效果