引言
小型直流减速电机是一个高度集成的动力执行单元,其核心由直流电机和齿轮减速箱两部分构成,具有体积小、扭矩大、可控性佳的特点。它通过PWM脉冲宽度调制即可实现宽范围的无级调速与灵活的正反转控制,被广泛应用于机器人、智能小车、自动化设备及智能家居等场景,是驱动各类机械运动的理想“关节”与“肌肉”。
本文将详细介绍如何利用STM32F407ZGT6的定时器产生PWM信号,通过TB6612FNG电机驱动芯片实现对两个直流减速电机的转速与方向控制。
1.核心硬件
(1)电机驱动模块(驱动芯片TB6612FNC)
相较于传统的L298N,TB6612是一款性能更优的双H桥驱动芯片,具有效率高、发热少、外围电路简单的特点。可同时驱动两个电机。TB6612FNG芯片引脚图及引脚功能见下图。
引脚
|
引脚功能说明
|
VM1~VM3
|
电机驱动电压输入(4.5V~13.5V)
|
PGND1、PGND2
|
电源地
|
VCC
|
逻辑电平输入端(2.7~5.5V)
|
GND
|
接地
|
AIN1、AIN2
|
A电机输入端
|
AO1、AO2
|
A电机输出端
|
PWMA
|
A电机PWM信号输入端
|
BIN1、BIN2
|
B电机输入端
|
AO1、AO2
|
B电机输出端
|
PWMB
|
B电机PWM信号输入端
|
STBY
|
正常工作(STBY=1)/待机状态(STBY=0)控制端
|
引脚信号与电机工作状态(以A电机为例,STBY=1。B电机同理。):1-高电平,0-低电平
PWMA
|
1
|
1
|
1
|
1
|
0
|
AIN1
|
0
|
1
|
0
|
1
|
X
|
AIN2
|
0
|
0
|
1
|
1
|
X
|
功能
|
制动停止
|
正转
|
反转
|
制动停止
|
停止
|
AIN1/AIN2(或BIN1/BIN2):方向控制引脚,决定电机的正反转。
PWMA(PWMB):PWM输入引脚,接收来自MCU的PWM信号,控制电机转速。
STBY(控制端):高电平使能芯片,低电平则所有电机停止。
常见的双路电机驱动模块和小型直流减速电机(带编码器)如下,电机控制引脚连接单片机,电机输出引脚连接电机。(E1A/E1B或E2A/E2B为电机编码器A相B相信号输出引脚)
驱动芯片TB6612FNC典型应用电路图如下。MCU连接电机输入端,电机连接输出端。
2.硬件连接(STBY直接接5V)
STM32F407引脚
|
TB6612引脚 |
功能说明
|
PA4/PA5
|
AIN1/AIN2
|
GPIO输出,控制电机A方向
|
PA2(TIM2_CH3)
|
PWMA
|
PWMA,控制电机A转速
|
PA3(TIM2_CH4)
|
PWMB
|
PWMB,控制电机B转速
|
PB0/PB1
|
BIN1/BIN2
|
GPIO输出,控制电机B方向
|
3.代码实现
(1)正反转控制引脚配置
/* 控制A和B电机正反转引脚PA4 - AIN1 / PA5 - AIN2PB0 - BIN1 / PB1 - BIN2 */void Motor_GPIO_Init(){/*1-定义结构体*/GPIO_InitTypeDef GPIO_InitStruct; //定义结构体/*2-开启GPIOA/B时钟*/RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //控制A电机正反转引脚RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //控制B电机正反转引脚/*3-初始化相关参数-A电机*/GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; //选择A4、A5引脚GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; //输出模式GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; //输出速度GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽输出GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // 上拉GPIO_Init(GPIOA, &GPIO_InitStruct);/*B电机*/GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //选择B0、B1引脚GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; //输出模式GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; //输出速度GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽输出GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // 上拉GPIO_Init(GPIOB, &GPIO_InitStruct);}
(2)PWM输出配置
/*PA2 — TIM2 CH3PA3 — TIM2 CH4*/void Motor_Init(){GPIO_InitTypeDef GPIO_InitStruct; //GPIO口结构体TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;//时基结构体TIM_OCInitTypeDef TIM_OCInitStruct;//比较输出结构体/*1-开定时器和GPIO口时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);/*2-配置定时器输出引脚*/GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_TIM2);//复用功能配置GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_TIM2);//复用功能配置GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;//选择A2 A3引脚GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//复用功能模式GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;//输出速度GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(GPIOA, &GPIO_InitStruct);/*3-时基配置*/TIM_TimeBaseStruct.TIM_Period =100-1;//自动重装载ARR值,周期10msTIM_TimeBaseStruct.TIM_Prescaler =8400-1;//预分频PSC值10KHzTIM_TimeBaseStruct.TIM_ClockDivision=TIM_CKD_DIV1;//1分频TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);//完成初始化/*4-比较输出配置-CH3*/TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性高电平TIM_OC3Init(TIM2, &TIM_OCInitStruct); //初始化TIM2比较输出通道3/*4-比较输出配置-CH4*/TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性高电平TIM_OC4Init(TIM2, &TIM_OCInitStruct); //初始化TIM2比较输出通道4/*5-使能预装载寄存器*/TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);/*6-使能自动重装载寄存器*/TIM_ARRPreloadConfig(TIM2, ENABLE);/*7-使能定时器*/TIM_Cmd(TIM2,ENABLE);}
(3)主函数
int main(void){Motor_GPIO_Init();Motor_Init();while(1){//A电机 正传GPIO_SetBits(GPIOA, GPIO_Pin_4);//AIN1-高GPIO_ResetBits(GPIOA, GPIO_Pin_5); //AIN2 -低//B电机正传GPIO_SetBits(GPIOB, GPIO_Pin_0);//BIN1-高GPIO_ResetBits(GPIOB, GPIO_Pin_1);//BIN2-低//PWMA PWMB 设置占空比 0~100TIM_SetCompare3(TIM2, 50);TIM_SetCompare4(TIM2, 50);}}//控制正反转和PWM占空比可以封装成函数
/*A电机B电机正转*/void Motor_forward(){GPIO_SetBits(GPIOA, GPIO_Pin_4);GPIO_ResetBits(GPIOA, GPIO_Pin_5);GPIO_SetBits(GPIOB, GPIO_Pin_0);GPIO_ResetBits(GPIOB, GPIO_Pin_1);}/*A电机B电机反转*/void Motor_reverse(){GPIO_SetBits(GPIOA, GPIO_Pin_5);GPIO_ResetBits(GPIOA, GPIO_Pin_4);GPIO_SetBits(GPIOB, GPIO_Pin_1);GPIO_ResetBits(GPIOB, GPIO_Pin_0);}/*设置两个电机的转速 0~100*/void Set_Speed(u8 MotorA_speed,u8 MotorB_speed){TIM_SetCompare3(TIM2, MotorA_speed);TIM_SetCompare4(TIM2, MotorB_speed);}
效果如下:

