ESP32 MCPWM驱动直流有刷电机
在驱动直流有刷电机的时候重点就是在于PWM信号。而ESP32 内部自带专给电机产生pwm的外设MCPWM。而我也是使用两对pwm分别驱动两个马达。
根据官方参考手册的描述,mcpwm一共有两个mcpwm外设,每个外设有三个定时器,每个定时器可以产生2路pwm,这样算下来也就是通过mcpwm最多可以产生2*3*2=12路(6对)pwm信号。每个外设都带有三路的捕获输入,可以用来对输入信号的脉宽测量,这样就不仅仅可以计数,也可以测量周期和占空比。但是因为我电机测速用的是霍尔,仅仅计数,就没用这个捕获功能,反而用的是pcnt。
好了,下面就解释下基于ESP32 IDF驱动电机的配置过程。
第一步:初始化mcpwm用到的gpio口:
1 2 3 4 5 6 7 8 9 10 11 12 |
#define MOTOL_GPIO1 19 #define MOTOL_GPIO2 21 #define MOTOR_GPIO1 2 #define MOTOR_GPIO2 4 #define MOTOR_MCPWM MCPWM_UNIT_0 #define MOTOL_TIMER MCPWM_TIMER_0 #define MOTOR_TIMER MCPWM_TIMER_1 //初始化需要的四个gpio口 mcpwm_gpio_init(MOTOR_MCPWM, MCPWM0A, MOTOL_GPIO1); mcpwm_gpio_init(MOTOR_MCPWM, MCPWM0B, MOTOL_GPIO2); mcpwm_gpio_init(MOTOR_MCPWM, MCPWM1A, MOTOR_GPIO1); mcpwm_gpio_init(MOTOR_MCPWM, MCPWM1B, MOTOR_GPIO2); |
第二步:对mcpwm外设进行初始化
1 2 3 4 5 6 7 8 |
mcpwm_config_t pwm_config; 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(MOTOR_MCPWM, MOTOL_TIMER, &pwm_config); //Configure PWM0A & PWM0B with above settings mcpwm_init(MOTOR_MCPWM, MOTOR_TIMER, &pwm_config); //Configure PWM1A & PWM1B with above settings |
第三步:就可以通过接口函数,设置对应的通道引脚为高、为低、或是有PWM波形
1 2 3 |
mcpwm_set_signal_low(MOTOR_MCPWM, MOTOL_TIMER, MCPWM_OPR_A); mcpwm_set_duty(MOTOR_MCPWM, MOTOL_TIMER, MCPWM_OPR_B, 90); mcpwm_set_duty_type(MOTOR_MCPWM, MOTOL_TIMER, MCPWM_OPR_B, MCPWM_DUTY_MODE_0); //call this each time, if operator was previously in low/high state |
需要注意:mcpwm_set_duty和mcpwm_set_duty_type 这两个函数必须要同时调用来控制一个通道引脚上产生pwm波形。
我这个只是个很简单的应用,实际上mcpwm还有很多功能没有用到,需要控制无刷等复杂电机的可以去做深入研究,而控制有刷直流电机上面三个步骤就够了!