(二)【平衡小车制作】电机驱动(超详解)

news2024/11/16 8:22:17

一、硬件设计

1.直流减速电机
  直流减速电机,即齿轮减速电机,是在普通直流电机的基础上,
加上配套齿轮减速箱。齿轮减速箱的作用是,提供较低的转速,较大的力矩。
  简单的来说,STM32分配两个IO口给一个直流减速电机,并给予高低电平,来使得电机进行正转或反转

在这里插入图片描述

我用的电机为GM25-370直流减速电机(带霍尔编码器),工作电压:6-24VDC,额定电压12V,额定电流0.65A,空载转速350RPM,额定功率5W,最大精度,1496CPR,配备 CPR霍尔AB两相编码器,减速后输出单圈374个正交脉冲。

2.TB6612FNG电机驱动芯片

        要实现小车的转向与前进后退控制,我们可以使用STM32实现,但是STM32的IO口带负载能力较弱,而直流电机是大电流感性负载,所以我们需要功率放大器件,在这里,我选择使用TB6612FNG这款电机驱动芯片。
  TB6612FNG 是东芝半导体公司生产的一款直流电机驱动器件,它具有大电流MOSFET-H 桥结构,双通道电路输出,可同时驱动 2 个电机。相比于 L298N的热耗性和外围二极管续流电路,TB6612FNG无需外加散热片,外围电路简单,只需外接电源滤波电容就可以直接驱动电机,利于减小系统尺寸。对于PWM信号输入频率范围,我采用10KHz的频率,并通过改变占空比调节电机的速度。

平衡小车中使用到的引脚:
  电机1——PB12/PB13
  电机2——PB14/PB15
  PWM1——PA8
  PWM2——PA11

在这里插入图片描述

在这里插入图片描述 

3.H桥驱动电路

        上面说到TB6612FNG 具有大电流MOSFET-H桥结构,那么很多小伙伴想问:什么是H桥结构呢?我以下面两张图举例,帮助大家简单化理解H桥电路结构。
注:图中的电路Q1,Q2,Q3,Q4为三极管,而TB6612内部集成的是四个MOSFET,我以下图举例,大家不可把下图看做是TB6612内部电路,其内部电路可查看TB6612的参考手册。
 

① 当Q1,Q4导通,Q2,Q3关断时,电流从Q1,从电机正极通过电机负极,再从Q4流出,完成一条回路,电机Motor正转。

在这里插入图片描述

 ① 当Q2,Q3导通,Q1,Q4关断时,电流从Q3,从电机负极通过电机正极,再从Q2流出,完成一条回路,电机Motor反转。

在这里插入图片描述

二、软件编程

1.电机驱动函数——motor.c
1)电机GPIO初始化函数
 入口参数:

  • 初始化GPIO–PB12、PB13、PB14、PB15为推挽输出
void Motor_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);// 开启时钟
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;// 初始化GPIO--PB12、PB13、PB14、PB15为推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);	
}

2)限幅函数
 入口参数:电机A脉冲个数,电机B脉冲个数

  • 限制电机的脉冲个数在规定范围内,有个最值,即自动重装载值(我设置的是PWM_MAX = 7200,PWM_MIN = -7200)
void Limit(int *motoA,int *motoB)
{
	if(*motoA>PWM_MAX)*motoA=PWM_MAX;
	if(*motoA<PWM_MIN)*motoA=PWM_MIN;
	
	if(*motoB>PWM_MAX)*motoB=PWM_MAX;
	if(*motoB<PWM_MIN)*motoB=PWM_MIN;
}

 3)绝对值函数(非常通用,建议保存!!)
 入口参数:常规变量

  • 通过与0比较,大于0则返回不变的值,小于0则返回相反的值。
int abs(int p)
{
	int q;
	q=p>0?p:(-p);
	return q;
}

4)赋值函数
 入口参数:电机A脉冲个数,电机B脉冲个数

  • 入口参数即为PID运算完成后的最终PWM值(后续会讲解PID算法的实现)
void Load(int moto1,int moto2)
{
	//1.研究正负号,对应正反转
	if(moto1>0)	
    	Ain1=1,Ain2=0;//正转
	else 				
    	Ain1=0,Ain2=1;//反转
	//2.研究PWM值
	TIM_SetCompare1(TIM1,abs(moto1));
	
  	//1.研究正负号,对应正反转
	if(moto2>0)
    	Bin1=1,Bin2=0;
	else 				
    	Bin1=0,Bin2=1;	
  	//2.研究PWM值
	TIM_SetCompare4(TIM1,abs(moto2));
}

2.电机驱动函数头文件——motor.h

#ifndef  _MOTOR_H
#define  _MOTOR_H

#include "sys.h" 

#define Ain1  PBout(14)
#define Ain2  PBout(15)

#define Bin1  PBout(13)
#define Bin2  PBout(12)

void Motor_Init(void);
void Limit(int *motoA,int *motoB);
int abs(int p);
void Load(int moto1,int moto2);
#endif

3.PWM函数——pwm.c

1. 定时器初始化函数
 入口参数:预分频值,自动重装载值

  • PA8,PA11复用推挽输出
  • 对应定时器1通道1和通道4
  • 开启MOE主输出使能(高级定时器特有!!!)
void PWM_Init_TIM1(u16 Psc,u16 Per)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_OCInitTypeDef TIM_OCInitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO,ENABLE);//开启时钟
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;        // 初始化GPIO--PA8、PA11为复用推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8 | GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);  // 初始化定时器。
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period=Per;
	TIM_TimeBaseInitStruct.TIM_Prescaler=Psc;
	TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);   // TIM1
	
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;      // 初始化输出比较
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse=0;
	TIM_OC1Init(TIM1,&TIM_OCInitStruct);
	TIM_OC4Init(TIM1,&TIM_OCInitStruct);
	
	TIM_CtrlPWMOutputs(TIM1,ENABLE);// 高级定时器专属!!!--MOE主输出使能
	
	TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC1预装载寄存器使能
	TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC4预装载寄存器使能
	TIM_ARRPreloadConfig(TIM1,ENABLE);// TIM1在ARR上预装载寄存器使能
	
	TIM_Cmd(TIM1,ENABLE);           // 开定时器。
}

4.PWM函数头文件——pwm.h

#ifndef  _PWM_H
#define  _PWM_H

#include "sys.h" 

void PWM_Init_TIM1(u16 Psc,u16 Per);
#endif

以上就是平衡小车系列文章第二讲——电机驱动,包括硬件结构讲解和STM32软件编程的讲解,文章中出现错误或者小伙伴对以上内容有所疑问,欢迎大家在评论区留言,小政看到后会尽快回复大家!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/494083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCoed 2, 23, 25, 112, 113

文章目录 1. 两数相加2. K 个一组翻转链表3. 合并 K 个升序链表4. 路径总和I5. 路径总和II 1. 两数相加 题目详情见: LeetCode2. 两数相加 题目描述相对来说比较绕, 我们可以直接理解为两个多位的整数相加, 只不过整数的每一位都是通过链表进行存储; 比如, 整数 342, 通过链表…

使用Webpack搭建项目(vue篇)

本篇承接使用Webpack搭建项目&#xff08;react篇&#xff09; 由于大部分配置一样&#xff0c;我们从上一篇react项目中&#xff0c;复制webpack.dev.js以及webpack.prod.js 开发模式 1.删除ReactRefreshWebpackPlugin 2.自动补充拓展名修改为.vue文件&#xff0c;同时处理…

每天一道算法练习题--Day21 第一章 --算法专题 --- ----------位运算

我这里总结了几道位运算的题目分享给大家&#xff0c;分别是 136 和 137&#xff0c; 260 和 645&#xff0c; 总共加起来四道题。 四道题全部都是位运算的套路&#xff0c;如果你想练习位运算的话&#xff0c;不要错过哦&#xff5e;&#xff5e; 前菜 开始之前我们先了解下…

【linux的学习与软件安装】

文章目录 linux的学习一、工具安装与联网&#xff1f;二、Linux软件安装1.安装jdk2.安装MySQL安装redis linux的学习 一、工具安装与联网&#xff1f; 1.1安装好VM后 进入vi /etc/sysconfig/network-scripts/ifcfg-ens33 然后ip addr 查看ip 1.2打开IDEA的tools 二、Linux软…

网络编程 | 多进程多线程并发服务器代码实现

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

5.5 Mybatis Update标签实战,返回值是什么? 教你通常处理做法

本文目录 前言一、update标签实战① 在UserMapper接口中新增update方法② MybatisX插件生成update标签③ 写update SQL 语句 二、update sql返回值是什么?三、Mybatis update标签返回值是什么?四、实现简易的修改密码API1. dal层2. service层3. web层自测通过 五、Git提交最后…

vue - 常见的移动端rem适配方案

移动端rem适配方案 rem适配原理方案1&#xff1a;rem媒体查询方案2&#xff1a;jsrem方案3&#xff1a;vwrem&#xff08;不用查询屏幕宽度&#xff09; 移动端适配经常使用的就是 rem; 主要有以下几种方案&#xff1a; 1&#xff1a;rem 媒体查询&#xff08;media&#xff0…

蓝桥杯最后一战

目录 分巧克力_二分 题目描述 输入格式 输出格式 输入输出样例 说明/提示 代码&#xff1a; 巧克力 - 优先队列 题目描述 输入格式 输出格式 输入输出样例 说明/提示 代码&#xff1a; 思路分析&#xff1a; 秘密行动_dp 蓝桥杯算法提高-秘密行动 题目描述 …

Unity之OpenXR+XR Interaction Toolkit 安装和配置

前言 XR Interaction Toolkit 是Unity基于OpenXR标准&#xff0c;发布的一套XR工具&#xff0c;目的是方便我们快速接入XR相关的SDK&#xff0c;并且做到兼容不同VR设备的目的&#xff0c;目前流行的VR设备如Oculus&#xff0c;Metal&#xff0c;HTC Vive&#xff0c;Pico等统…

改进YOLOv8 | 主干网络篇 | YOLOv8 更换骨干网络之 MobileNetV3 | 《搜寻 MobileNetV3》

论文地址:https://arxiv.org/abs/1905.02244 代码地址:https://github.com/xiaolai-sqlai/mobilenetv3 我们展示了基于互补搜索技术和新颖架构设计相结合的下一代 MobileNets。MobileNetV3通过结合硬件感知网络架构搜索(NAS)和 NetAdapt算法对移动设计如何协同工作,利用互…

【天秤座区块链】元宇宙知识普以及简单解读清华研究报告

本节目录 温馨提示关于分栏【天秤座区块链】由来提前感受元宇宙区块链的两个注意点区块链革命简单认识清华大学报告解读&#xff08;元宇宙&#xff09;前传《雪崩》元宇宙具体是什么&#xff1f;元宇宙不是什么&#xff1f;那为什么要冲击元宇宙呢&#xff1f; 小补充及感谢 温…

前端搭建打字通游戏(内附源码)

The sand accumulates to form a pagoda ✨ 写在前面✨ 打字通功能介绍✨ 页面搭建✨ 样式代码✨ 功能实现 ✨ 写在前面 上周我们实通过前端基础实现了名言生成器&#xff0c;当然很多伙伴再评论区提出了想法&#xff0c;后续我们会考虑实现的&#xff0c;今天还是继续按照我们…

java基础入门-06-【面向对象进阶(多态包final权限修饰符代码块)】

Java基础入门-06-【面向对象进阶&#xff08;多态&包&final&权限修饰符&代码块&#xff09;】 14、面向对象进阶&#xff08;多态&包&final&权限修饰符&代码块&#xff09;1.1 多态的形式1.2 多态的使用场景1.3 多态的定义和前提1.4 多态的运行…

嵌入式设备逆向所需的工具链

导语&#xff1a;本文介绍了嵌入式设备逆向所需的工具链。 相关的应用程序或工具有&#xff1a; UART(Universal Asynchronous Receiver Transmitter&#xff0c;通用异步收发器)&#xff1a; UBoot&#xff1b; Depthcharge&#xff1b; SPI (Serial Peripheral Interface…

利用文本描述替换万物(Inpaint-Anything-Description)

文章目录 引言安装Demo github&#xff1a; https://github.com/Atlas-wuu/Inpaint-Anything-Description 引言 前段时间看了万物分割SAM、文生图Stable Diffusion、开集检测Grounding DINO&#xff0c;它们之间可以互相补充&#xff0c;AIGC变得更加可控。Inpaint Anything将…

RK3568平台开发系列讲解(网络篇)Linux 的 socket 套接字

🚀返回专栏总目录 文章目录 一、套接字的数据结构1.1、struct socket 数据结构1.2、struct sock 数据结构二、套接字的初始化三、套接字与文件四、Socket Buffer沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 Linux 内核支持的套接字如下: 我们创建套接字时,可以…

PCIe物理层弹性缓存机制(详细)解析-PCIe专题知识(四)

目录 前言一、简介二、详细解析2.1 实例解析2.2 具体实现过程 三、总结四、其他相关链接1、PCI总线及发展历程总结2、PCIe物理层总结-PCIE专题知识&#xff08;一&#xff09;3、PCIe数据链路层图文总结-PCIe专题知识&#xff08;二&#xff09;4、PCIe物理层链路训练和初始化总…

国产ChatGPT命名图鉴

很久不见这般热闹的春天。 随着ChatGPT的威名席卷全球&#xff0c;大洋对岸的中国厂商也纷纷亮剑&#xff0c;各式本土大模型你方唱罢我登场&#xff0c;声势浩大的发布会排满日程表。 有趣的是&#xff0c;在这些大模型产品初入历史舞台之时&#xff0c;带给世人的第一印象其…

进程替换函数组介绍exec*

目录 前述 execl execlp execle execv execvp execvpe 前述 介绍后缀的意义&#xff1a; l &#xff08;list&#xff09;&#xff1a;表示参数采用列表。 v&#xff08;vector&#xff09;&#xff1a;参数同数组表示。 p&#xff08;path&#xff09;&#xff1a;自…

力扣题库刷题笔记704-二分查找

1、题目如下&#xff1a; 2、个人Python代码如下&#xff1a; 个人代码如下&#xff1a; class Solution: def search(self, nums: List[int], target: int) -> int: left 0 right len(nums) - 1 while left < right: mid (right left) >> 1 if nums[mid] >…