esp32用mcpwm驱动电机

目录

前言

目录

配置

操作

例程1

例程1解析


本篇为乐鑫官方文档,地址:Motor Control Pulse Width Modulator (MCPWM) - ESP32 - — ESP-IDF 编程指南 latest 文档

前言

看下图可以非常清楚的看到ESP32 有两个 MCPWM 单元,分别是MCPWM_UNIT_0和MCPWM_UNIT_1。

每个 MCPWM 单元有三个定时器,分别是下图中的数字标号0,1,2。

每个定时器可以产生2路pwm,分别是下图中的A和B。

也就是说通过mcpwm最多可以产生2*3*2=12路(6对)pwm信号。可用于控制不同的电机。每个单元有三对 PWM 输出 。(从下图可以非常清晰的看到

esp32用mcpwm驱动电机_第1张图片

 此外,在文章中,每个MCPWM单元的单个信号的输出标记为PWMxA/PWMxB。

例如MCPWM_UNIT_0的六路pwm输出,从上到下可以标记为PWM0A/PWM0B,PWM1A/PWM1B,PWM2A/PWM2B。MCPWM_UNIT_1同理。

MCPWM单元的更详细框图如下所示。每个A/B对可由三个定时器0、1和2中的任意一个定时器计时。同一定时器可用于对多对PWM输出进行计时。每个单元还能够收集同步信号等输入,检测电机过流或过压等故障信号,以及获取转子位置等捕捉信号的反馈。

esp32用mcpwm驱动电机_第2张图片

本API的描述从配置MCPWM的定时器和发电机子模块开始,以提供基本的电机控制功能。然后讨论了故障处理器、信号捕获和载波的更高级子模块和功能。 

目录

配置输出的基本功能

操作输出以驱动电机

调整电机的驱动方式

同步同步计时器以协同工作

捕获外部信号以提供对输出的额外控制

使用故障处理程序检测和管理故障

如果输出信号通过隔离变压器,则添加更高频率的载波

额外的分辨率配置

配置

配置范围取决于电机类型,特别是需要多少输出和输入,以及驱动电机的信号顺序。

在这种情况下,我们将描述一种简单的配置,用于控制仅使用部分可用MCPWM资源的有刷直流电机。下面显示了一个示例电路。它包括一个H桥,用于切换施加在电机(M)上的电压的极化,并提供足够的电流来驱动电机。

esp32用mcpwm驱动电机_第3张图片

1.选择用于驱动电机的MCPWM装置。ESP32板上有两个可用单元,并在mcpwm_单元中列出。

2.通过调用mcpwm_gpio_init()初始化两个gpio作为所选单元内的输出信号。这两个输出信号通常用于命令电机向右或向左旋转。mcpwm\u io\u signals\t中列出了所有可用的信号选项。要一次设置多个管脚,请将函数mcpwm_set_pin()与mcpwm_pin_config_t一起使用。

3.定时器的选择。该装置内有三个定时器。定时器在mcpwm\u timer\t中列出。

4.在mcpwm配置结构内设置定时器频率和初始占空比。

5.如有必要,通过调用mcpwm_group_set_resolution()和mcpwm_timer_set_resolution()设置计时器分辨率

6.调用函数mcpwm_init()和上述参数,使配置生效

操作

例程1
 

#include "driver/mcpwm.h"
#include "soc/mcpwm_reg.h"
#include "soc/mcpwm_struct.h"

#define MOTO_GPIO1  18
#define MOTO_GPIO2  5
//步骤一:选择mcpwm_unit
#define MOTOR_MCPWM_UNIT MCPWM_UNIT_0

//初始化需要的四个gpio口

void setup(){
//步骤二:用选定的mcpwm_unit来初始化gpio口
    mcpwm_gpio_init(MOTOR_MCPWM_UNIT, MCPWM0A, MOTO_GPIO1);
    mcpwm_gpio_init(MOTOR_MCPWM_UNIT, MCPWM0B, MOTO_GPIO2);  
//步骤三:用mcpwm_init()这个函数为这个mcpwm_unit选定一个定时器,
#define MOTO_TIMER MCPWM_TIMER_0
    mcpwm_config_t pwm_config;
//步骤四:通过mcpwm_config_t结构体为定时器设置频率和初始值
    pwm_config.frequency = 1000;    //frequency = 500Hz,
    pwm_config.cmpr_a = 0;    //duty cycle of PWMxA = 0
    pwm_config.cmpr_b = 0;    //duty cycle of PWMxb = 0
    pwm_config.counter_mode = MCPWM_UP_COUNTER;
    pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
    
//步骤五:调用mcpwm_init()函数使得配置生效
    mcpwm_init(MOTOR_MCPWM_UNIT, MOTO_TIMER, &pwm_config);    //Configure PWM0A & PWM0B with above settings

    
}

void loop(){
     mcpwm_set_signal_low(MOTOR_MCPWM_UNIT, MOTO_TIMER, MCPWM_OPR_A);
     mcpwm_set_duty(MOTOR_MCPWM_UNIT, MOTO_TIMER, MCPWM_OPR_B, 30);
     mcpwm_set_duty_type(MOTOR_MCPWM_UNIT, MOTO_TIMER, MCPWM_OPR_B, MCPWM_DUTY_MODE_0); //call this each time, if operator was previously in low/high state 
}

例程1解析

通过mcpwm_config_t结构体,我们可以新建一个mcpwm设置的结构体,进行相关设置,例如mcpwm的频率(frequency),

/**
 * @brief MCPWM config structure
 */
typedef struct {
    uint32_t frequency;              /*!

接下来,就可以通过接口函数,设置对应的通道引脚为高、为低、或是有PWM波形。

通过调用 mcpwm _ set _ duty _ type ()可以改变 PWM 信号的相位,最后一个参数是表示mcpwm相位的,通过查看下面源码,我们可以看到这是个枚举类型。

typedef enum {
    MCPWM_DUTY_MODE_0 = 0, /*!

所以,需要注意的是mcpwm_set_duty和mcpwm_set_duty_type  这两个函数必须要同时调用来控制一个通道引脚上产生pwm波形 。毕竟想要控制波形不光要有占空比,还需要相位。

我们看上述例程中最后一行代码,其中MCPWM_DUTY_MODE_1代表高电平占空比,MCPWM_DUTY_MODE_0代表低电平占空比。

esp_err_t mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, mcpwm_duty_type_t duty_type);

 我们来看看不同代码的效果:

mcpwm_set_duty(MOTOR_MCPWM_UNIT, MOTO_TIMER, MCPWM_OPR_B, 30);
mcpwm_set_duty_type(MOTOR_MCPWM_UNIT, MOTO_TIMER, MCPWM_OPR_B, MCPWM_DUTY_MODE_0);

效果 

esp32用mcpwm驱动电机_第4张图片

mcpwm_set_duty(MOTOR_MCPWM_UNIT, MOTO_TIMER, MCPWM_OPR_B, 30);
mcpwm_set_duty_type(MOTOR_MCPWM_UNIT, MOTO_TIMER, MCPWM_OPR_B, MCPWM_DUTY_MODE_1);

效果 

esp32用mcpwm驱动电机_第5张图片

MCPWM.h

/*
 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

#include "soc/soc_caps.h"
#if SOC_MCPWM_SUPPORTED
#include "esp_err.h"
#include "soc/soc.h"
#include "driver/gpio.h"
#include "esp_intr_alloc.h"
#include "hal/mcpwm_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief IO signals for the MCPWM
 *
 *        - 6 MCPWM output pins that generate PWM signals
 *        - 3 MCPWM fault input pins to detect faults like overcurrent, overvoltage, etc.
 *        - 3 MCPWM sync input pins to synchronize MCPWM outputs signals
 *        - 3 MCPWM capture input pins to gather feedback from controlled motors, using e.g. hall sensors
 */
typedef enum {
    MCPWM0A = 0,        /*!