【ESP32 Arduino平衡小车制作】(三) 直流电机pwm控制

基于ESP32的直流电机PWM控制

直流电机驱动器

驱动器使用 H桥电路进行驱动,核心电路 H 桥加上一些必要的外围电路,共同组成直流有刷电机的驱动器。H 桥本身可作为集成电路使用,也可由分立元件构成。

集成电路形式的 H 桥一般用于中小功率需求的应用,或者是对电路面积有要求的场合。

分立元件形式的 H 桥通常用于大功率或者超大功率需求的应用,主要由 MOSFET 或 IGBT 晶体管组成。

这里我使用的是TB6612这款直流驱动芯片

可利用IN1和IN2这两个输入信号,选择正转,反转,短路制动器、和停机等四种模式的其中一种模式。

【ESP32 Arduino平衡小车制作】(三) 直流电机pwm控制_第1张图片

二、ESP32 - PWM(LEDC)输出

LED_PWM 主要用于控制 LED 的亮度和颜色,也可以产生 PWM 信号用于其他用途。

LED_PWM 有 16 路通道,即 8 路高速通道和 8 路低速通道。这 16 路通道能够产生独立的数字波形来驱动 RGB LED 设备。

高速或低速通道可以由四个高速定时器之一或四个低速定时器之一进行驱动。 PWM 控制器还能够自动逐渐增加或减少占空比,在无须处理器干预的情况下实现亮度和颜色渐变。 LED_PWM 还支持小数分频。

方法函数:

double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits)

(通道号,频率,计数位数)
channel为通道号,取值0 ~ 15;
freq,设置频率;
resolution_bits计数位数,取值0 ~ 20(该值决定后面ledcWrite方法中占空比的最大值,如该值写10,则占空比最大可写2^10-1=1023 ;
通道最终频率 = 时钟频率 / ( 分频系数 * ( 2^计数位数 ) );(分频系数最大为1024)
该方法返回值:最终频率;


void ledcWrite(uint8_t channel, uint32_t duty)

(通道,占空比)
指定通道输出一定占空比的波形;


double ledcWriteTone(uint8_t channel, double freq)

(通道,频率)
当外接无源蜂鸣器的时候可用该函数,发出某种音色(根据频率不同而不同);


double ledcWriteNote(uint8_t channel, note_t note, uint8_t octave)

(通道,调式,音阶)
该方法是上面方法的进一步封装,可以直接输出指定调式和音阶声音的信号,参数如下:
note:调式,取值为NOTE_C, NOTE_Cs, NOTE_D, NOTE_Eb, NOTE_E, NOTE_F, NOTE_Fs, NOTE_G, NOTE_Gs, NOTE_A, NOTE_Bb, NOTE_B
octave音阶,取值0~7;


uint32_t ledcRead(uint8_t channel)

(通道)
返回指定通道占空比的值;


double ledcReadFreq(uint8_t channel)

(通道)
返回指定通道当前频率(如果当前占空比为0 则该方法返回0);


void ledcAttachPin(uint8_t pin, uint8_t channel)

(引脚,通道)
绑定:将LEDC通道投射到指定IO口上;


void ledcDetachPin(uint8_t pin)

(引脚)
解除绑定:解除IO口的LEDC功能;


以上参考:
1、《esp32_技术参考手册.pdf》
2、使用Arduino开发ESP32(十三):PWM(LEDC)
3、玩转 ESP32 + Arduino (三) GPIO和串口

三、电机控制程序

#include 
#include 

//TB6612FNG驱动模块控制信号 共6个
#define IN1 14  //控制电机1的方向A,01为正转,10为反转 
#define IN2 12  //控制电机1的方向B,01为正转,10为反转 
#define IN3 27  //控制电机2的方向A,01为正转,10为反转 
#define IN4 26  //控制电机2的方向B,01为正转,10为反转 

#define PWMA 25	//控制电机1 PWM控制引脚
#define PWMB 33 //控制电机2 PWM控制引脚

#define freq 50000 		 //PWM波形频率5KHZ
#define pwm_Channel_1  0 //使用PWM的通道0
#define pwm_Channel_2  1 //使用PWM的通道1

#define resolution  10		//使用PWM占空比的分辨率,占空比最大可写2^10-1=1023
#define interrupt_time_control 15//定时器15ms中断控制时间

/**************************************************************************
函数功能:赋值给PWM寄存器 
入口参数:左轮PWM、右轮PWM
返回  值:无
**************************************************************************/
void Set_Pwm(int moto1, int moto2)
{
	int Amplitude = 900;  //===PWM满幅是1024 限制在950
	
	if (moto1 > 0)   digitalWrite(IN1, HIGH),      digitalWrite(IN2, LOW);  //TB6612的电平控制
	else             digitalWrite(IN1, LOW),       digitalWrite(IN2, HIGH); //TB6612的电平控制
	
	if (moto2 > 0)   digitalWrite(IN3, LOW),      digitalWrite(IN4, HIGH); //TB6612的电平控制
	else             digitalWrite(IN3, HIGH),     digitalWrite(IN4, LOW); //TB6612的电平控制
	
	//功能:限制PWM赋值 
	if (moto1 < -Amplitude)  moto1 = -Amplitude;
	if (moto1 >  Amplitude)  moto1 =  Amplitude;
	if (moto2 < -Amplitude)  moto2 = -Amplitude;
	if (moto2 >  Amplitude)  moto2 =  Amplitude;
	
	//赋值给PWM寄存器 
	ledcWrite(pwm_Channel_1,abs(moto1));
	ledcWrite(pwm_Channel_2,abs(moto2));
}

void control(void)
{
	Set_Pwm(50,50); //这里仅仅设置占空比为50%,电机转速50%
} 

/*********************************setup**********************************/
void setup()
{
    pinMode(IN1, OUTPUT);          //TB6612控制引脚,控制电机1的方向,01为正转,10为反转
    pinMode(IN2, OUTPUT);          //TB6612控制引脚,
    pinMode(IN3, OUTPUT);          //TB6612控制引脚,控制电机2的方向,01为正转,10为反转
    pinMode(IN4, OUTPUT);          //TB6612控制引脚,
    pinMode(PWMA, OUTPUT);         //TB6612控制引脚,电机PWM
    pinMode(PWMB, OUTPUT);         //TB6612控制引脚,电机PWM

    digitalWrite(IN1, 0);          //TB6612控制引脚拉低
    digitalWrite(IN2, 0);          //TB6612控制引脚拉低
    digitalWrite(IN3, 0);          //TB6612控制引脚拉低
    digitalWrite(IN4, 0);          //TB6612控制引脚拉低
  
    ledcSetup(pwm_Channel_1, freq, resolution);	//PWM通道一开启设置
    ledcAttachPin(PWMA, pwm_Channel_1);			//PWM通道一和引脚PWMA关联
    ledcWrite(pwm_Channel_1, 0);				//PWM通道一占空比设置为零
    
    ledcSetup(pwm_Channel_2, freq, resolution); //PWM通道二开启设置
    ledcAttachPin(PWMB, pwm_Channel_2);			//PWM通道二和引脚PWMB关联
    ledcWrite(pwm_Channel_2, 0);				//PWM通道二占空比设置为零
    
    timer_control.attach_ms(interrupt_time_control, control); //定时器中断开启
}

/************************************loop************************************/
void loop()
{

}

你可能感兴趣的:(ESP32,单片机,stm32,嵌入式硬件)