使用STM32定时器输出PMW信号配置TB6612 驱动芯片,是嵌入式的经典方案。
一、硬件接线与引脚功能
直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作。TB6612是一款双通道驱动芯片,控制一个电机需要3个STM32引脚(1个PWM+2个GPIO),具体如下:
1、PWM引脚(PWMA和PWMB)连接STM32的定时器通道引脚(比如TIM3_CHI1对应PA6),输入PWM信号,占空比决定电机转速。
2、方向控制引脚(AIN1-AIN2):连接STM32的普通GPIO,通过高低电平组合控制电机的正转、反转和刹车;
3、使能引脚(STBY):芯片的总开关。接3.3V和5V高电平表示使能,接GND则芯片进入待机高阻态,电机自由滑行。
4、电源引脚(VM,VCC):VM接5V,官方不超过10V。VCC接3.3V,务必保证STM32、TB6612和电源共地(GND)。
二、TB6612核心控制逻辑
STBY接3.3V,一直使能,逻辑如下:
|--------|--------|-------------|------------|
| AN1 | AN2 | PWMA(PWM信号) | 电机状态 |
| 高电平(1) | 低电平(0) | 有效PWM | 正转,占空比越大越快 |
| 低电平(0) | 高电平(1) | 有效PWM | 反转,占空比越大越快 |
| 低电平(0) | 低电平(0) | X | 停机 |
| 高电平(1) | 高电平(1) | X | 制动 |
三、代码
配置:使用TIM2,通道1→PA0,PA4接AIN1,PA5接AIN2。

1、PWM初始化及修改占空比函数
cpp
void PWM_Init(uint16_t ARR,uint16_t PSC)
{
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_OCInitTypeDef OC_Config;
//开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//初始化GPIO,PA0复用功能
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//初始化时基单元
TIM_BaseInitStructure.TIM_ClockDivision =TIM_CKD_DIV1;
TIM_BaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
TIM_BaseInitStructure.TIM_Period =ARR;//1000-1
TIM_BaseInitStructure.TIM_Prescaler =PSC;//72-1
TIM_TimeBaseInit(TIM2,&TIM_BaseInitStructure);
//配置OC
OC_Config.TIM_OCMode =TIM_OCMode_PWM1;
OC_Config.TIM_OutputState = TIM_OutputState_Enable;
OC_Config.TIM_OCPolarity = TIM_OCPolarity_High;
OC_Config.TIM_Pulse = 0;
TIM_OC1Init(TIM2,&OC_Config);
TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM2,ENABLE);
TIM_Cmd(TIM2,ENABLE);
}
//修改CCR值,也就是修改占空比
void SetCompare(uint16_t Compare)
{
TIM_SetCompare1(TIM2,Compare);
}
注:PWM当成模板,只要修改ARR、PSC即可。公式:频率=72M/(ARR+1)/(PSC+1);
PSC=72-1,ARR=1000-1,TB6612用这个参数频率噪音很小,比较适合。
2、TB6612引脚初始化
cpp
void Motor_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4 |GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
/*上电默认停机*/
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
}
3、电机启停函数
cpp
void Motor_Forward()
{
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
GPIO_SetBits(GPIOA,GPIO_Pin_4);
}
void Motor_Reverse()
{
GPIO_SetBits(GPIOA,GPIO_Pin_5);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
}
void Motor_Stop()
{
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
}
4、main函数
cpp
#include "stm32f10x.h"
#include "Delay.h"
#include "Motor.h"
#include "KEY.h"
#include "PWM.h"
int main()
{
PWM_Init(1000-1,72-1);
Motor_Init();
while(1)
{
Motor_Forward();
SetCompare(600);
Delay_ms(5000);
SetCompare(1000);
Delay_ms(10000);
Motor_Stop();
Delay_ms(10000);
}
}
注:PWM频率选择:TB6612支持高频,可以将PWM设置在10~20kHz之间,这个频率超出了人耳听觉范围,可以有效消除电机运行时的想"啸叫声"。
四、复习GPIO
1、输出引脚(单片机往外发信号)
分:普通输出、复用输出。
1)普通推挽Out_PP:是人写代码手动控制高低电平:点灯、TB6612的AIN1和AIN2、继电器、按键指示灯、蜂鸣器等。函数:GPIO_SetBits(),GPIO_ResetBits()等,完全由程序说了算,和片内外设无关。
2)复用推挽AF__PP(专用外设输出)
引脚交给单片机硬件模块自动控制,自己写的代码不能直接拉高拉低。
TIM_CHx(PWM)、串口TX,SPI时钟、MOSI。定时器自动产生方波,软件干预不了电平,必须开复用模式。
共同点:都是输出,单片机向外送出电平。
3)开漏输出:基本不用,只有I2C偶尔使用。
2、输入引脚(单片机读取外部的电平)
1))上拉输入IPD:外部开关、独立按键最常用;
2)浮空输入:IN_FLOATING:ADC模拟量采集;
3)复用输入AF_IPD:串口Rx、SPI_MISO、定时器捕获
外设接管引脚用来接收信号,就用复用输入;
2、判断流程:
第一步:引脚是往外输出还是外部信号??
读取→输入:按键选IPD,串口选Rx选复用AF_IPD;ADC选浮空;
往外输出→进入第二步:
第二步:是自己手动写代码控制电平吗??
自己操控→Out_PP;
定时器/串口自动发波形→AF_PP(比如PWM)
本文完!