当前位置: 首页 > ai >正文

直流电机驱动与TB6612

直流电机是一种将电能转换为机械能的装置,有两个电极,当电极正接时,电机正转,当电极反接时,电机反转。作为大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作。而这时候就需要用到TB6612模块。作为一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向。

它的功能类似 L298N,但是:

效率更高(采用 MOSFET,导通电阻低,发热小)

体积更小

电压范围更宽(驱动电压 2.5V13.5V,逻辑电压 2.7V5.5V)

最大电流更大(连续 1.2A,每路可达 3.2A 峰值)

TB6612FNG 引脚功能

引脚功能说明
VCC逻辑电源2.7V ~ 5.5V(接 STM32 3.3V/5V)
VM电机电源2.5V ~ 13.5V(接电池/电源给电机供电)
GND系统地,逻辑和电机地要共地
PWMA电机A PWM控制电机A转速(接 STM32 PWM 输出)
AIN1电机A方向控制1和 AIN2 组合确定方向
AIN2电机A方向控制2和 AIN1 组合确定方向
AO1、AO2电机A输出接电机A 两端
PWMB电机B PWM控制电机B转速
BIN1、BIN2电机B方向控制同 A 通道
BO1、BO2电机B输出接电机B 两端
STBY芯片使能高电平芯片工作,低电平待机(必须接高电平或 MCU 控制)

1.控制原理

方向由 IN1、IN2 决定,转速由 PWM 控制。

方向控制真值表

IN1IN2电机状态
00停止(制动模式,电机两端短接)
10正转
01反转
11停止(制动模式)

PWM 调速

PWMA/PWMB 接 MCU 的 PWM 输出。

占空比 0% → 电机停止

占空比 50% → 半速

占空比 100% → 全速

2.STM32 控制代码

main.c

#include "stm32f10x.h"      // STM32 标准外设库头文件,包含寄存器定义
#include "Delay.h"          // 延时函数
#include "OLED.h"           // OLED 显示驱动
#include "Motor.h"          // 电机控制模块
#include "Key.h"            // 按键输入模块uint8_t KeyNum;             // 存储按键值(0 表示没按,1 表示按下 Key1)
int8_t Speed;               // 电机速度变量,范围 -100~100,正负决定方向int main(void)
{OLED_Init();            // 初始化 OLED,配置 I2C/SPIMotor_Init();           // 初始化电机控制相关 IO(PA4/PA5 + PWM 输出 PA2)Key_Init();             // 初始化按键 GPIOOLED_ShowString(1, 1, "Speed:");   // OLED 第一行显示文字“Speed:”while (1){KeyNum = Key_GetNum();         // 扫描按键,返回 0 或 1if (KeyNum == 1)               // 如果按下了按键 1{Speed += 20;               // 每按一次,速度加 20if (Speed > 100)           // 如果超过 100{Speed = -100;          // 从 -100 重新开始(反转全速)}}Motor_SetSpeed(Speed);         // 设置电机速度和方向(核心函数)OLED_ShowSignedNum(1, 7, Speed, 3); // 在 OLED 第 1 行第 7 列显示带符号速度值}
}

Motor.c

#include "stm32f10x.h"      // STM32 标准外设库头文件
#include "PWM.h"            // PWM 驱动模块void Motor_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能 GPIOA 时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      // 推挽输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;// 选择 PA4 和 PA5GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     // IO 速度GPIO_Init(GPIOA, &GPIO_InitStructure);                // 初始化 GPIOA4/A5PWM_Init();                                           // 初始化 PWM(PA2 → TIM2_CH3)// TB6612 接线说明:// PA4 → AIN1// PA5 → AIN2// PA2 → PWMA(PWM 占空比)
}void Motor_SetSpeed(int8_t Speed)
{if (Speed >= 0) // Speed >= 0 → 电机正转{GPIO_SetBits(GPIOA, GPIO_Pin_4);   // AIN1 = 1GPIO_ResetBits(GPIOA, GPIO_Pin_5); // AIN2 = 0PWM_SetCompare3(Speed);            // 设置 PWM 占空比 = Speed// TB6612 判定:AIN1=1,AIN2=0 → 正转// PWM 输入:Speed 值越大,占空比越大,转速越快}else            // Speed < 0 → 电机反转{GPIO_ResetBits(GPIOA, GPIO_Pin_4); // AIN1 = 0GPIO_SetBits(GPIOA, GPIO_Pin_5);   // AIN2 = 1PWM_SetCompare3(-Speed);           // 占空比取 Speed 的绝对值// TB6612 判定:AIN1=0,AIN2=1 → 反转// PWM 输入:|Speed| 值越大,占空比越大,转速越快}
}

PWM.c

#include "stm32f10x.h"      // STM32 标准外设库头文件void PWM_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 开启 TIM2 时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 开启 GPIOA 时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;      // 复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;            // PA2 → TIM2_CH3GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // IO 输出速度GPIO_Init(GPIOA, &GPIO_InitStructure);               // 初始化 PA2TIM_InternalClockConfig(TIM2);                       // 使用内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 不分频TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;      // ARR = 99,决定 PWM 精度(0~99)TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1;    // PSC = 35,定时器时钟 = 72MHz/36 = 2MHzTIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; // 不重复TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);// PWM 周期 = (ARR+1) * (PSC+1) / 72MHz = 100*36/72MHz = 20kHz// → 电机驱动推荐 20kHz,超声波频率,听不到啸叫TIM_OCInitTypeDef TIM_OCInitStructure;TIM_OCStructInit(&TIM_OCInitStructure);              // 初始化结构体TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;    // PWM 模式 1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 高电平有效TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能通道输出TIM_OCInitStructure.TIM_Pulse = 0;                   // CCR 初始值=0,占空比=0%TIM_OC3Init(TIM2, &TIM_OCInitStructure);             // 配置 TIM2_CH3 → PA2TIM_Cmd(TIM2, ENABLE);                               // 启动 TIM2
}void PWM_SetCompare3(uint16_t Compare)
{TIM_SetCompare3(TIM2, Compare); // 设置 TIM2->CCR3 = Compare// 实际占空比 = Compare / (ARR+1) = Compare / 100// 例如:Compare=50 → 占空比50% → 电机得到一半电压 → 半速
}

Speed → 判断正负 → 控制 AIN1/AIN2 (PA4/PA5) → 控制电机正反转

Speed 的绝对值 → 写进 CCR3 → 生成 PWM → 控制 PWMA (PA2) → 控制转速

key.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"void Key_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);
}uint8_t Key_GetNum(void)
{uint8_t KeyNum = 0;if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0){Delay_ms(20);while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);Delay_ms(20);KeyNum = 1;}if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0){Delay_ms(20);while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);Delay_ms(20);KeyNum = 2;}return KeyNum;
}

http://www.xdnf.cn/news/19069.html

相关文章:

  • Excel数组学习笔记
  • 【开题答辩全过程】以 基于JSP的养生网站系统为例,包含答辩的问题和答案
  • 本地部署商业服务器 Glassfish 并实现外部访问
  • Rust 安装与运行指南
  • Jetson进行旋转目标检测推理实现大疆无人机飞行控制
  • Git 9 ,.git/index.lock 文件冲突问题( .git/index.lock‘: File exists. )
  • 卷积神经网络为什么要填充(Padding)
  • 基于无人机的风电叶片全自动智能巡检:高精度停角估计与细节优先曝光调控技术
  • 在做题中学习(89):合并区间
  • 如何去除edge浏览器的灰色边框
  • idea2023.3遇到了Lombok失效问题,注释optional和annotationProcessorPaths即可恢复正常
  • Redis与MySQL数据不一致问题
  • 【MYSQL | 基础篇 多表查询】
  • FunctionAI 图像生成:简化从灵感到 API 调用的每一步
  • Kingbase-Mysql兼容模式下LOAD DATA INFILE语法再体验
  • idea控制台从properties中取值然后打印出现控制台乱码问题
  • (论文速读)MAPTNet——少样本表面缺陷分割方法
  • Java图形图像处理【基础篇】【二】
  • 前端-什么是Vue
  • DMZ层Nginx TLS 终止与安全接入配置实战20250829
  • OpenCV 图像轮廓检测与相关技术全解析
  • 三维铸件模型分解:基于微分几何与拓扑结构的分析方法
  • Ubuntu虚拟机磁盘空间扩展指南
  • 基于LangChain框架搭建AI问答系统(附源码)
  • InnoDB存储引擎底层拆解:从页、事务到锁,如何撑起MySQL数据库高效运转(下)
  • MySQL 中如何解决深度分页的问题?
  • 嵌入式接口通识知识之RGB接口
  • 基于机器学习的多个模型的预测Backtrader自动化交易系统设计
  • 关于shell命令的扩展
  • AlexNet:点燃深度学习革命的「卷积神经网络之王」