【平衡小车制作】(二)电机驱动(超详解)
大家好,我是小政。本篇文章我将针对平衡小车中的电机控制进行详细的讲解,驱动一个电机最重要的就是给它一个PWM信号,PWM的概念、如何驱动电机及通过改变PWM占空比进行电机调速我会在本篇文章中进行详解。让每位小伙伴能够对PWM(脉冲宽度调制)和电机控制有更加清晰的理解。
一、硬件设计
1.直流减速电机
直流减速电机,即齿轮减速电机,是在普通直流电机的基础上,加上配套齿轮减速箱。齿轮减速箱的作用是,提供较低的转速,较大的力矩。
简单的来说,STM32分配两个IO口给一个直流减速电机,并给予高低电平,来使得电机进行正转或反转。
我用的电机为GM25-370直流减速电机(带霍尔编码器),工作电压:6-24VDC,额定电压12V,额定电流0.65A,空载转速350RPM,额定功率5W,最大精度,1496CPR,配备 CPR霍尔AB两相编码器,减速后输出单圈374个正交脉冲。
图1 GM25-370直流减速电机(带霍尔编码器)
图2 霍尔编码器接口引脚
2.TB6612FNG电机驱动芯片
要实现小车的转向与前进后退控制,我们可以使用STM32实现,但是STM32的IO口带负载能力较弱,而直流电机是大电流感性负载,所以我们需要功率放大器件,在这里,我选择使用TB6612FNG这款电机驱动芯片。
TB6612FNG 是东芝半导体公司生产的一款直流电机驱动器件,它具有大电流MOSFET-H 桥结构,双通道电路输出,可同时驱动 2 个电机。相比于 L298N的热耗性和外围二极管续流电路,TB6612FNG无需外加散热片,外围电路简单,只需外接电源滤波电容就可以直接驱动电机,利于减小系统尺寸。对于PWM信号输入频率范围,我采用10KHz的频率,并通过改变占空比调节电机的速度。
特点:
- T每通道输出最高1.2A的连续驱动电流,启动峰值电流达2A/3.2A(连续脉冲/单脉冲);
- 4种电机控制模式:正转/反转/制动/停止;
- PWM支持频率高达100kHz;
- 待机状态;
- 片内低压检测电路与热停机保护电路;
- 工作温度:-20~85°C
- 封装:SSOP24(画PCB时注意!)
引脚介绍:
- VM1:电源输入(电机输入电源),这里我设置为12V。
- VCC:驱动电源输入(驱动芯片),这里我设置为5V。
- GND:芯片上的地都是共地。
- STNDBY:总使能端,相当于EN,高电平有效,这里直接与VCC连接。
- PWMA,PWMB:从MCU输入,我设置10Khz的PWM频率
- AIN1,AIN2:电机状态控制。
- A0,A1,B0,B1:输出到电机。
平衡小车中使用到的引脚:
电机1——PB12/PB13
电机2——PB14/PB15
PWM1——PA8
PWM2——PA11
图3 TB6612FNG电机驱动芯片
图4 AN1和AN2引脚高低电平对应电机状态
3.H桥驱动电路
上面说到TB6612FNG 具有大电流MOSFET-H桥结构,那么很多小伙伴想问:什么是H桥结构呢?我以下面两张图举例,帮助大家简单化理解H桥电路结构。
注:图中的电路Q1,Q2,Q3,Q4为三极管,而TB6612内部集成的是四个MOSFET,我以下图举例,大家不可把下图看做是TB6612内部电路,其内部电路可查看TB6612的参考手册。
这里推荐给大家一个查找芯片的网址:http://www.semiee.com/(半岛小芯)
① 当Q1,Q4导通,Q2,Q3关断时,电流从Q1,从电机正极通过电机负极,再从Q4流出,完成一条回路,电机Motor正转。
图5 H桥电路:电机正转
① 当Q2,Q3导通,Q1,Q4关断时,电流从Q3,从电机负极通过电机正极,再从Q2流出,完成一条回路,电机Motor反转。
图6 H桥电路:电机反转
二、软件编程
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); // TIM1TIM_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软件编程的讲解,文章中出现错误或者小伙伴对以上内容有所疑问,欢迎大家在评论区留言,小政看到后会尽快回复大家!
【平衡小车制作】(三)编码器讲解(超详解)
https://blog.csdn.net/weixin_44270218/article/details/113195466
【平衡小车制作】(二)电机驱动(超详解)相关推荐
- 【平衡小车制作】(一)硬件原理图讲解(超详解)
大家好,我是小政.之后的一系列文章我将介绍我玩平衡小车的过程以及遇到的一些问题,将这些内容记录下来分享给大家,也让大家少走一些弯路.接下来我将从硬件框架选择.软件编程.PID算法.PID调参.蓝牙 ...
- 【平衡小车制作】(七)串级PID调参及平衡成果展示(超详解)
大家好,我是小政.本篇文章我将针对PID调参进行详细的讲解,让每位小伙伴能够对比例.积分.微分三个参数如何调节有更加清晰的理解. 一.调参步骤 确立机械中值 直立环(内环)--Kp极性.Kp大小. ...
- 【Java二维数组】(超详解)
[Java二维数组](超详解) 什么是二维数组 二维数组的定义格式 访问二维数组 什么是二维数组 元素为一维数组的数组就称为二维数组 二维数组的定义格式 格式一:元素的数据类型[][] 数组的名字 = ...
- 嘉立创电路板制作过程全流程详解(二):沉铜、线路
上一篇文章,我们了解了第1道和第2道工序,MI和钻孔,这篇文章,我们将了解第3道工序和第4道工序:沉铜和线路. 看上一篇文章,点击这里: 嘉立创电路板制作过程全流程详解(一):MI.钻孔 第3道工序: ...
- Android vector标签 PathData 画图超详解
此文章来源于https://www.cnblogs.com/yuhanghzsd/p/5466846.html点击打开链接 Android vector标签 PathData 画图超详解 SVG是一种 ...
- TT马达平衡小车制作
TT马达平衡小车制作 假期无聊本来买个淘宝的寻迹小车套件,做了个寻迹小车和遥控功能.后来看到了平衡小车就想搞一个. 去搜了方案基本都是平衡小车之家的编码器电机和车模,一搜好几百,学生党不太买得起. 还 ...
- 平衡小车制作系列之八——总结
文章目录 一. 前言 二. 说在最前面 2.1 模块总结 2.2 时间分配(2 Weeks In All) 2.3 一些问题 三. 收获与总结 四. 碎碎念 一. 前言 本博客原题目叫做"我 ...
- python控制手机模拟器_Appium+python自动化之连接模拟器并启动淘宝APP(超详解)...
简介 上一篇讲解完模拟器的安装.配置好以后,就好比我们手机已经买好,并且系统已经做好了,就差我们用数据线和电脑连接开始实战了,这篇宏哥就带着小伙伴们和童鞋们趁热打铁,讲解和分享一下如何连接模拟器(电脑 ...
- 线性规划之单纯形法【超详解+图解】-转载
线性规划之单纯形法[超详解+图解] 目录 1.作用 2.线性规划的一般形式 5.1几何意义 5.2如何判断最优 5.3如何选择新的基变量 5.4如何选择被替换的基变量 5.5终止条件 标准型: 转化为 ...
- 嘉立创电路板制作过程全流程详解(五):测试、锣边、V-CUT、QC、发货
第1篇文章,点击这里:嘉立创电路板制作过程全流程详解(一):MI.钻孔 第2篇文章,点击这里:嘉立创电路板制作过程全流程详解二:沉铜.线路 第3篇文章,点击这里:嘉立创电路板制作过程全流程详解三:图电 ...
最新文章
- 欢迎大家踊跃报名担当“讲师”
- 久坐的危害和解决方式
- centos6.5系统自带python2.6升级到python2.7
- MTK 驱动开发(32)---Sensor 移植及调试2
- Admob的PIN码接收教程
- python最新抢票脚本
- jetty 去掉项目名称访问
- C# 获取系统开机时间
- JavaScript能做什么 单行注释 多行注释
- 新房子没网络,怎么用光猫和路由器上网
- 利用appimage工具对开发好的项目进行打包
- 王者荣耀角色信息在哪个服务器,怎么查询王者荣耀角色在哪个区
- python加油代码_python入门教程NO.5 用python写个自动选择加油站的小程序
- 【C语言指针】 指针+-整数、指针-指针、解引用、指针数组、二级指针、结构体声明、初始化、传参
- C# WinForm应用程序的多语言环境支持
- 龙芯1b(LS1B200)使用LVGL7.0.1组件的滑杆控件控制三色RGB灯的亮度
- kflash下载地址分享
- 电阻学习看这篇就够了
- 自动化测试-selenium IDE使用
- Apache修改默认站点的目录
热门文章
- Error: PostCSS received undefined instead of CSS string核心解决方法
- python实现excel单元格合并_Python_pandas实现excel工作表合并功能
- PS制作gif动图教程
- 苹果mac怎么连接打印机? mac系统添加共享打印机的技巧
- 利用讯飞语音识别技术开发离线语音控制系统(Windows平台)
- Matlab中对坐标轴的对数转化,loglog,semilogx与semilogy
- Android 关于推送通知还需要一些其他的设置问题
- C++:使用类方法根据四点计算四面体体积
- 【小墨mysql】mysql系列之一---索引
- TBtools:基因家族分析简单流程