本帖最后由 闵丨大 于 2019-8-26 21:35 编辑
此内容由EEWORLD论坛网友闵丨大原创,如需转载或用于商业用途需征得作者同意并注明出处
硬件使用TB6612FNG+uFUN学习板(STM32F103RCT6)。实现效果:PWM控制电机正转5s--停止等待1s--反转5s--正转5s,往复运动。
1.TB6612FNG电机驱动模块
此模块比L298N效率高、体积少且在额定范围内其芯片基本不发热。
引脚说明
A控制信号输入---PWMA
|
VM ---电机驱动电压输入端(3.3V-12V)
|
A电机输入端2 ---AIN2
|
VCC ---逻辑电平输入端(2.7V-5.5V)
|
A电机输入端1 ---AIN1
|
GND --- 接地
|
正常工作/待机状态控制端---STBY
|
AO1 --- A电机输出端1
|
B电机输入端1---BIN1
|
AO2 --- A电机输出端2
|
B电机输入端2---BIN2
|
BO2 --- B电机输出端2
|
B控制信号输入端---PWMB
|
BO1 --- B电机输出端1
|
接地---GND
|
GND --- 接地
|
注:市面上TB6612FNG模块引脚分布有两种,二者区为其中一个引脚名称不一样。A类称为STBY,B类称为NC。小弟使用的就是B类,NC引脚可悬空也可接高电平。若A类STBY则必须接高电平,电机才能转动。下表为TB6612FNG逻辑真值表
2.TB6612FNG逻辑真值表
输入
|
输出
|
IN1
|
IN2
|
PWM
|
STBY
|
01
|
02
|
模式
|
H
|
H
|
H/L
|
H
|
L
|
L
|
制动
|
L
|
H
|
H
|
H
|
L
|
H
|
反转
|
L
|
H
|
L
|
H
|
L
|
L
|
制动
|
H
|
L
|
H
|
H
|
H
|
L
|
正转
|
H
|
L
|
L
|
H
|
L
|
L
|
制动
|
L
|
L
|
H
|
H
|
OFF
|
停止
|
H/L
|
H/L
|
H/L
|
L
|
OFF
|
待机
|
3.接线方式
4.源代码(关键部分)
//main函数部分
/*
硬件:TB6612FNG+uFUN开发板(STM32F103RCT6)
引脚定义:
TB6612电机驱动
VM——12V电池+ AO1——左电机+ BO2——右电机+
VCC——3.3或5V AO2——左电机- BO1——右电机-
GND——12V电池- AIN1——PB12 BIN1——PB15
STBY——3.3或5V AIN2——PB13 BIN2——PB14
PWMA——PA6(TIM3_CH1) PWMB——PA7(TIM3_CH2)
*/
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "EXTI.h"
void PWM_GPIO_Init(void);
int Moto1,Moto2; //电机PWM变量 应是Motor的 向Moto致敬
float Angle_Balance,Gyro_Balance; //平衡倾角 平衡陀螺仪 转向陀螺仪
//float Acceleration_Z; //Z轴加速度计
int main(void)
{
Stm32_Clock_Init(9); //=====系统时钟设置
delay_init(); //延时函数初始化
uart_init(43000); //初始化串口1
TB6612_Init(); //电机逻辑初始化
PWM_GPIO_Init();
TIM3_PWM_Init(7199,0); //不分频。PWM频率=72000/(7199+1)=10Khz
TIM_SetCompare1(TIM3,3600);
TIM_SetCompare2(TIM3,3600);
while(1)
{
delay_ms(1000);
Go(1);
delay_ms(5000);
Stop();
delay_ms(1000);
Go(0);
delay_ms(5000);
Stop();
}
}
void PWM_GPIO_Init(){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //led管脚配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
}
|
//TB6612_Init()函数配置部分
#include "tb6612.h"
#include "stm32f10x.h"
void TB6612_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//初始化PB12~PB15.用于连接到 TB6612 的In1-In4口。
//6612 上In1-In4口的作用是用其接收到的逻辑信号(高低电平)来控制电机的正反转。
}
void Go(int flag) //flag==1 正转 flag==0 反转
{
if(flag==1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_15);
GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14);
}
if(flag==0)
{
GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_15);
GPIO_ResetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14);
}
}
void Stop(void)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
}
|
//PWM配置部分
#include "PWM.h"
void TIM3_PWM_Init(u16 arr,u16 psc) //arr为自动重装载寄存器周期的值,psc为TIM2的预分频值
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器2时钟
//初始化TIM
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM Channe PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM3
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM3, ENABLE);
}
|