esp32外设使用-MCPWM基本使用方法

  • 概述
    • 主要用途
  • PWM基本输出配置
    • 关键函数
    • 动态控制函数
    • 示例程序
  • 死区时间设置
    • 原理说明
    • 函数说明
    • 示例程序
  • 定时器同步
    • 关键函数说明
    • 示例程序
  • 参考

概述

主要用途

  • 有刷/无刷电机驱动
  • 开关电源
  • DAC
  • 脉冲宽度计算,测距/测速
  • FOC驱动

PWM基本输出配置

关键函数

主要包括IO设置、分辨率设置和MCPWM初始化,分辨率设置值决定了输出PWM的频率,定时器周期寄存器只有16bit,因此分辨率不宜过大或过小,过大有可能计数值超范围,过小则有可能不够计数,需根据实际输出pwm频率范围确定,mcpwm_init()函数执行后会自动启动PWM输出。

//头文件
#include "driver/mcpwm.h"//设置MCPWM的某个IO
esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, //MCPWM_UNIT_0 / MCPWM_UNIT_1/*********************************** io_signal:*  MCPWM0A / MCPWM0B / MCPWM1A / MCPWM1B / MCPWM2A / MCPWM2B: pwm输出信号*     MCPWM_SYNC_0 / MCPWM_SYNC_1 / MCPWM_SYNC_2:同步输入信号*   MCPWM_FAULT_0 / MCPWM_FAULT_1 / MCPWM_FAULT_2:故障输入信号*    MCPWM_CAP_0 / MCPWM_CAP_1 / MCPWM_CAP_2:捕获输入信号* ************************************/mcpwm_io_signals_t io_signal, int gpio_num);//GPIO号//设置一组MCPWM的IO管脚
esp_err_t mcpwm_set_pin(mcpwm_unit_t mcpwm_num,//组号 0/1const mcpwm_pin_config_t *mcpwm_pin)//管脚配置信息如下:
mcpwm_pin_config_t mcpwm_pin= {.mcpwm0a_out_num = 1,//实际IO号.mcpwm0b_out_num = 2,.mcpwm1a_out_num = 3,.mcpwm1b_out_num = 4,.mcpwm2a_out_num = 5,.mcpwm2b_out_num = 6,.mcpwm_cap0_in_num   = 7,.mcpwm_cap1_in_num   = 8,.mcpwm_cap2_in_num   = 9,.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 = 10,.mcpwm_fault1_in_num = -1,  //Not used.mcpwm_fault2_in_num = -1   //Not used
};//设置mcpwm分辨率,相当于MCPWMx所使用的时钟,需在mcpwm_init()之前调用
esp_err_t mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num, unsigned long int resolution);//MCPWM号(0/1)、分辨率(默认:10,000,000)//设置定时器分辨率,相当于计数器的计数时钟,决定了计数器精度,需在mcpwm_init()之前调用
esp_err_t mcpwm_timer_set_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, unsigned long int resolution)//定时器号(0/1/2) 、分辨率(默认1,000,000) 当设置输出频率≥分辨率时将不能输出。//初始化并启动一组MCPWM
esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num,//组号 0/1mcpwm_timer_t timer_num, //定时器号 0/1/2const mcpwm_config_t *mcpwm_conf);//配置如下:
mcpwm_config_t mcpwm_conf = {.frequency = 1000, //输出pwm波形频率 Hz.cmpr_a = 22.3,     //操作器A输出占空比, i.e duty_a = 62.3.cmpr_b = 42.8,     //操作器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:输出强制为高********************************************/.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_DOWN_COUNTER};

动态控制函数

//强制输出高电平 / 低电平
esp_err_t mcpwm_set_signal_high or mcpwm_set_signal_low (mcpwm_unit_t mcpwm_num, //MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num, //MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2mcpwm_generator_t gen)//MCPWM_GEN_A / MCPWM_GEN_B//启动/停止MCPWM输出
esp_err_t mcpwm_start(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
esp_err_t mcpwm_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)//设置占空比类型
esp_err_t mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num, //MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num, //MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2mcpwm_generator_t gen, //MCPWM_GEN_A / MCPWM_GEN_B/********************************************duty_type (占空比类型):*    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_type_t duty_type)
//动态调整占空比-比例调整
esp_err_t mcpwm_set_duty(mcpwm_unit_t mcpwm_num, //MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num, //MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2mcpwm_generator_t gen, //MCPWM_GEN_A / MCPWM_GEN_Bfloat duty)//0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低
//动态调整占空比-按时间调整(us)
esp_err_t mcpwm_set_duty_in_us(mcpwm_unit_t mcpwm_num, //MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num, //MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2mcpwm_generator_t gen, //MCPWM_GEN_A / MCPWM_GEN_Buint32_t duty_in_us)// x(us)
//获取当前占空比-返回比例值
float mcpwm_get_duty(mcpwm_unit_t mcpwm_num, //MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num, //MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2mcpwm_operator_t gen)//MCPWM_GEN_A / MCPWM_GEN_B//设置PWM输出频率
esp_err_t mcpwm_set_frequency(mcpwm_unit_t mcpwm_num, //MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num, //MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2uint32_t frequency)//频率值(Hz)
//获取当前频率值
uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, //MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num)//MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2

示例程序

本示例程序配置MCPWM0的定时器0输出5KHz的PWM,并每5ms动态调整占空比,需要注意的是系统默认tick速率位100Hz(10ms),不能延迟小于10ms,需进行以下修改,改为1ms(1000Hz)即可。

#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"void app_main(void)
{mcpwm_pin_config_t mcpwm_pin = {.mcpwm0a_out_num = 14, //实际IO号.mcpwm0b_out_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};//设置PWM定时器分辨率ESP_ERROR_CHECK(mcpwm_set_pin(MCPWM_UNIT_0, &mcpwm_pin));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 = 10000, //输出pwm波形频率 Hz.cmpr_a = 0,        //操作器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_DOWN_COUNTER};ESP_ERROR_CHECK(mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &mcpwm_conf));float j;while(1){for (j = 0.1; j < 100; j = j + 0.1){vTaskDelay(pdMS_TO_TICKS(5));ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_A,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_B,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低}for (j = 99.9; j > 0; j = j - 0.1){vTaskDelay(pdMS_TO_TICKS(5));ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_A,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_B,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低}}
}

效果展示:
示波器1通道—MCPWM0_TIMER0_A; 示波器2通道—MCPWM0_TIMER0_B;

死区时间设置

原理说明

死区时间 : MOS管都存在结电容,存在开关延迟,死区时间是为了保证上下桥臂的MOS管不会同时导通的时间,一般在us级
ESP32死区时间控制原理如下图所示,控制S1 to S7 开关可选择不同的死区时间配置模式。

设置开关不容易理解且繁琐,下面列出几种常用的工作模式:

MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE(高有效互补):
输出A与输入同相,不考虑死区时间时输出A与B互补(A=!B),死区时间内A=B。
MCPWM_ACTIVE_LOW_COMPLIMENT_MODE(低有效互补):
输出A与输入反相,不考虑死区时间时输出A与B互补(A=!B),死区时间内A=B。

MCPWM_ACTIVE_HIGH_MODE(高有效模式):
输出A与输入同相,不考虑死区时间时输出A与B相等(A=B),死区时间内A=!B。
MCPWM_ACTIVE_LOW_MODE(低有效模式):
输出A与输入反相,不考虑死区时间时输出A与B相等(A=B),死区时间内A=!B。

函数说明

//使能死区时间设置,必须在mcpwm_init()函数之后设置,否则无效。
esp_err_t mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num, // MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2mcpwm_deadtime_type_t dt_mode, //MCPWM_ACTIVE_HIGH/LOW_COMPLIMENT_MODE / MCPWM_ACTIVE_HIGH/LOW_MODEuint32_t red, //上升沿延迟: red x 100nsuint32_t fed) //下降沿延迟: fed x 100nsesp_err_t mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)// MCPWM_UNIT_0 / 1 and MCPWM_TIMER_0 / 1 / 2

示例程序

该程序展示死区时间配置,死区模块配置为高有效互补模式,输出只与A相关,因此只需要调整A的占空比即可。上升沿延迟和下降沿延迟均为10us,需注意mcpwm_deadtime_enable()函数需在mcpwm_init()函数之后执行,否则无效。

#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"void app_main(void)
{float j;mcpwm_pin_config_t mcpwm_pin = {.mcpwm0a_out_num = 14, //实际IO号.mcpwm0b_out_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};//设置PWM定时器分辨率ESP_ERROR_CHECK(mcpwm_set_pin(MCPWM_UNIT_0, &mcpwm_pin));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 = 10000, //输出pwm波形频率 Hz.cmpr_a = 0,        //操作器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_DOWN_COUNTER};ESP_ERROR_CHECK(mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &mcpwm_conf));ESP_ERROR_CHECK(mcpwm_deadtime_enable(MCPWM_UNIT_0,                      // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0,                     // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, // MCPWM_ACTIVE_HIGH/LOW_COMPLIMENT_MODE / MCPWM_ACTIVE_HIGH/LOW_MODE100,                               //上升沿延迟: red x 100ns100));                             //下降沿延迟: fed x 100nswhile (1){for (j = 20; j < 80; j = j + 0.1){vTaskDelay(pdMS_TO_TICKS(5));ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_A,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低}for (j = 80; j > 20; j = j - 0.1){vTaskDelay(pdMS_TO_TICKS(5));ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_A,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低}}
}

效果:
示波器1通道—MCPWM0_TIMER0_A; 示波器2通道—MCPWM0_TIMER0_B;

定时器同步

定时器同步用于对不同定时器之间计数值的同步,输入同步信号支持GPIO或来自其他定时器的同步输出信号。

关键函数说明

//初始化定时器同步子模块
esp_err_t mcpwm_sync_configure(mcpwm_unit_t mcpwm_num, // MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2const mcpwm_sync_config_t *sync_conf)//
//关闭定时器同步
esp_err_t mcpwm_sync_disable(mcpwm_unit_t mcpwm_num, // MCPWM_UNIT_0 / MCPWM_UNIT_1mcpwm_timer_t timer_num)// MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2
mcpwm_sync_config_t sync_cfg = {.sync_sig = MCPWM_SELECT_GPIO_SYNC0,//输入同步信号:MCPWM_SELECT_TIMER0/1/2_SYNC / MCPWM_SELECT_GPIO_SYNC0/1/2.timer_val = 0,//同步之后要载入的定时器值 0-999.count_direction = MCPWM_TIMER_DIRECTION_UP};//MCPWM_TIMER_DIRECTION_UP(递增)/ MCPWM_TIMER_DIRECTION_DOWN(递减)

示例程序

该程序启动MCPWM0中的Timer0和Timer1两个定时器,分别输出两个异步的PWM波,然后采用GPIO同步的方式,设置IO输出同步脉冲,进行软件同步。
注意:
该程序复用IO2即作为2个定时器的同步输入信号,又作为双向IO可进行软件置位/清零,IO复位后需先配置 mcpwm_set_pin() ,再配置IO方向,否则后面设置IO2高低电平函数不起作用。

#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"#define io_num(x) xvoid app_main(void)
{float j;// IO配置mcpwm_pin_config_t mcpwm_pin = {.mcpwm0a_out_num = io_num(14), //实际IO号.mcpwm0b_out_num = io_num(15),.mcpwm1a_out_num = io_num(4),.mcpwm1b_out_num = io_num(9),.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 = io_num(2), // 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};gpio_reset_pin(io_num(2));ESP_ERROR_CHECK(mcpwm_set_pin(MCPWM_UNIT_0, &mcpwm_pin));gpio_set_direction(io_num(2), GPIO_MODE_INPUT_OUTPUT);//设置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)ESP_ERROR_CHECK(mcpwm_timer_set_resolution(MCPWM_UNIT_0, MCPWM_TIMER_1, 1000000)); //定时器号(0/1/2)、分辨率(默认:1,000,000)mcpwm_config_t mcpwm_conf = {.frequency = 10000, //输出pwm波形频率 Hz.cmpr_a = 0,        //操作器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_DOWN_COUNTER};ESP_ERROR_CHECK(mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &mcpwm_conf)); //启动定时器0vTaskDelay(pdMS_TO_TICKS(50));                                         //增加两个定时器的启动延迟,产生明显异步效果便于观察ESP_ERROR_CHECK(mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_1, &mcpwm_conf)); //启动定时器1//同步配置mcpwm_sync_config_t sync_cfg = {.sync_sig = MCPWM_SELECT_GPIO_SYNC0,          //输入同步信号:MCPWM_SELECT_TIMER0/1/2_SYNC / MCPWM_SELECT_GPIO_SYNC0/1/2.timer_val = 0,                               //同步之后要载入的定时器值 0-999.count_direction = MCPWM_TIMER_DIRECTION_UP}; // MCPWM_TIMER_DIRECTION_UP(递增)/ MCPWM_TIMER_DIRECTION_DOWN(递减)ESP_ERROR_CHECK(mcpwm_sync_configure(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2&sync_cfg));   //同步配置ESP_ERROR_CHECK(mcpwm_sync_configure(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_1, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2&sync_cfg));   //同步配置//生成同步脉冲gpio_set_level(io_num(2), 0); // IO置低vTaskDelay(pdMS_TO_TICKS(5));gpio_set_level(io_num(2), 1); // IO置高vTaskDelay(pdMS_TO_TICKS(5));gpio_set_level(io_num(2), 0); // IO置低vTaskDelay(pdMS_TO_TICKS(5));while (1){for (j = 20; j < 80; j = j + 0.1){vTaskDelay(pdMS_TO_TICKS(5));ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_A,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_1, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_A,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低}for (j = 80; j > 20; j = j - 0.1){vTaskDelay(pdMS_TO_TICKS(5));ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_0, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_A,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低ESP_ERROR_CHECK(mcpwm_set_duty(MCPWM_UNIT_0,  // MCPWM_UNIT_0 / MCPWM_UNIT_1MCPWM_TIMER_1, // MCPWM_TIMER_0 / MCPWM_TIMER_1 / MCPWM_TIMER_2MCPWM_GEN_A,   // MCPWM_GEN_A / MCPWM_GEN_Bj));           // 0.0 to 100.0,精度为小数点后1位,设置0和100等效于强制输出高、低}}
}

效果:
不同步,示波器1通道—MCPWM0_TIMER0_A; 示波器2通道—MCPWM0_TIMER1_A;

同步之后:

参考

https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/peripherals/mcpwm.html

esp32外设使用-MCPWM基本使用方法相关推荐

  1. esp32外设使用-MCPWM故障处理模块使用

    esp32外设使用-MCPWM故障处理模块使用 概述 关键函数说明 示例代码 概述 每个MCPWM 外设都连接来自GPIO 矩阵的3 个故障信号(FAULT0,FAULT1 和FAULT2).这些信号 ...

  2. 几款常用esp32外设差异

    几款常用esp32外设差异 官网器件信息比较链接 从淘宝上看到这几款esp32卖的比较多,对比了下他们差异,感觉基本都差不多,主要差异点在ROM大小,SRAM,蓝牙,处理器核心,其中ESP32-S2的 ...

  3. 多核异构处理器对共享外设和资源的调配方法-飞凌嵌入式

    来源:飞凌嵌入式官网 www.forlinx.com 在多核异构CPU中,多个内核就如同多个大脑,而外设和内存等资源就如同手足,那么多个大脑该如何控制手足才能保证它们正常有序地运行呢? 以NXP i. ...

  4. patformio安装esp32环境的另一种方法

    关于platformio配置esp32环境 第一种方法我选择的是直接在初始化文件里改,让pio核心自己下载 但是这种方案实在是太慢了=.=,我下了一个晚上还没能结束. 所以我查了platformio的 ...

  5. ESP32 Wi-Fi 蓝牙 Tx Power 调整方法

    此篇博客用来整理 ESP32 Wi-Fi & BLE 的 Tx Power 调整方法.此博客分为两部分: Wi-Fi Tx Power 调整 BLE Tx Power 调整 BR/EDR Tx ...

  6. ESP8266/ESP32控制ws2812的几种方法

    ESP8266 ESP8266的GPIO有效翻转大约需要2.5us(0.4MHz),而ws2812的控制电平要求精度在百ns级别,所以直接控制GPIO比较难实现. 在网上搜索了一下各种可行的方案: A ...

  7. 外设位宽为8、16、32时,CPU与外设之间地址线的连接方法

    有不少人问到: flash连接CPU时,根据不同的数据宽度,比如16位的NOR FLASH (A0-A19),处理器的地址线要(A1-A20)左移偏1位.为什么要偏1位? 从软件和CPU的角度而言,一 ...

  8. 前端程序员常用的9大构建工具

    构建工具是一个把源代码生成可执行应用程序的过程自动化的程序(例如Android app生成apk).构建包括编译.连接跟把代码打包成可用的或可执行的形式. 在小型项目中,开发者往往手动调用构建过程,这 ...

  9. 使用arduino开发esp8266和esp32时首选项设置方法(附国内开发板管理网址)

    摘要:本文介绍arduino在开发esp8266和esp32时的首选项设置方法.其中给出的国内开发板管理器网址速度飞起. 基于esp8266开发的板子有很多种,例如D1等. esp8266的开发板管理 ...

最新文章

  1. c语言aba字母塔,打印字母金字塔,昨晚看到某个帖子的题目
  2. oracle外键死锁,Oracle技术之和外键相关的阻塞和死锁问题总结(二)
  3. WIX、Squarespace、WordPress 三者的优劣分别是什么?
  4. ux设计师薪水_我是如何从33岁的博物馆导游变成专业的Web开发人员和UX设计师的:我的…...
  5. Python接口测试
  6. oracle “**with as**”短语,也叫做子查询部分。
  7. 第九章 限制性图谱和正则表达式
  8. 使用Arcpy进行数据批处理-批量裁剪
  9. win10计算机拨号连接,拨号连接设置(Win10怎么设置宽带自动连接 win10开机自动连接宽带设置方法详解)...
  10. 卷积神经网络(CNN)卷积核与滤波器理解
  11. android的listview分组显示的时候layout_marginTop失效的解决办法
  12. 简单高效的图片降噪方法
  13. 【HTML5+CSS】怎样去美化你的页面
  14. 学习Android启动初始化 App StartUp
  15. Electron桌面应用打包流程详情
  16. 更愿意思念更早的“金陵”
  17. 病毒感染高峰期错过考研怎么办?社科院与杜兰金融管理硕士项目是你强大的后盾
  18. MethodType用法和setattr区别
  19. 破解 Kotlin 协程(6) - 协程挂起篇
  20. C# 使用系统时间做随机数种子,随机数算法

热门文章

  1. 最全的android工具方法集类
  2. 影响贝佐斯的12本书
  3. 贝佐斯超马斯克率先上天!乘坐自家火箭,扶摇直上100公里
  4. c语言 filetype ppt,c语言完整课件_图文.ppt
  5. 从Hadoop框架讨论大数据生态
  6. css实现立体正方形旋转效果
  7. Java遍历Set集合方法
  8. 学习率(Learing Rate)的作用以及如何调整
  9. Python工程师薪资再次刷新IT标准,月入20K,眼红了么?
  10. Java执行cmd命令