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

2023-05-16

  大家好,我是小政。本篇文章我将针对平衡小车中的电机控制进行详细的讲解,驱动一个电机最重要的就是给它一个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);   // 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软件编程的讲解,文章中出现错误或者小伙伴对以上内容有所疑问,欢迎大家在评论区留言,小政看到后会尽快回复大家!
【平衡小车制作】(三)编码器讲解(超详解)
https://blog.csdn.net/weixin_44270218/article/details/113195466

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【平衡小车制作】(二)电机驱动(超详解) 的相关文章

  • WebPack4学习实践笔记(一)

    一 准备 nodejs安装教程 xff1a https blog csdn net FED AF article details 105747632 xff09 二 安装 xff08 1 xff09 全局安装 初始化npm C Users
  • 可重入锁(又名递归锁)

    可重入锁 指的是同一线程外层函数获得锁之后 xff0c 内层递归函数仍能获取该锁的代码 xff0c 在同一线程的外层获取锁的时候 xff0c 在进入内层方法会自动获取锁 xff0c 也就是说线程可以任意进入它已经拥有的锁的同步代码块 syn
  • Java 读取TXT文件-行读取

    Java 读取TXT文件 行读取 span class token keyword public span span class token keyword static span String span class token funct
  • springMVC 指定文件 压缩下载

    span class token keyword package span span class token namespace com span class token punctuation span lyt span class to
  • HC-SR04超声波模块

    1 硬件原理图 2 传感器参数表 电气参数HC SR04 超声波模块工作电压DC 5 V工作电流15mA工作频率40kHz最远射程4m最近射程2cm测量角度15 度输入触发信号10uS 的 TTL 脉冲输出回响信号输出 TTL 电平信号 x
  • STM32F1系列-UCOSIII配置之delay_init()函数详解

    一 时钟选择 SysTick CLKSourceConfig xff08 xff09 xff1b 选择systick时钟 xff0c 函数配置的寄存器如下所示 找到该函数的定义 xff0c 其两个参数的数值如下 该函数选择的参数是SysTi
  • xfce4-session: Unable to access file /home/user/.ICEauthority: Permission denied

    wsl想要运行startxfce4却出现错误 xff1a usr bin startxfce4 X server already running on display 172 18 64 1 0 xfce4 session Unable t
  • YOLO 目标框回归(三)

    边框预测公式分析 Cx xff0c Cy 是 feature map 中 grid cell 的左上角坐标 xff1b Pw xff0c Ph 是预设的 anchor box 映射到 feature map 中的宽和高 最终得到的边框坐标值
  • 【机器人学】机器人运动学基础

    文章目录 DH table参考MDHSDH 齐次变换矩阵左乘 右乘左右乘与DH参数 欧拉角欧拉角的奇异性欧拉角万向节死锁 四元数齐次变换矩阵 欧拉角 轴角和四元数之间的转化关系机器人pieper准则 DH table DH参数可以说是机器人
  • 【IKFast】IKFast配置与使用

    文章目录 参考Fast of All环境什么是IKFast安装openRave相关Create Collada File For Use With OpenRAVECreate IKFast Solution CPP File验证从仿真验证
  • 2019.11.12-最新大华摄像机SDK开发,预览实时视频并指定码流格式保存到文件中(可观看)

    大华摄像机SDK开发 预览实时视频并指定码流格式保存到文件中 由于本人最近在开发大华摄像机 特此分享一些经验给到各位开发朋友 本次实例是关于大华摄像机的实时预览视频码流保存到文件中的Demo 本人还开发过海康威斯的SDK 如果有需要的话看我
  • 树莓派3下载安装Android系统图文教程

    树莓派3怎样安装Android系统 xff1f 树莓派3相比上一代性能增强很多 xff0c 采用64位四核1 2GHz处理器 xff0c 搭载1GB LPDDR2内存 xff0c 虽然配置仅相当于入门级Android手机 xff0c 但运行
  • 海康威视摄像机SDK二次开发-JavaDemo环境搭建详解

    由于此前写了两篇具体功能实现的博文 但是发现好多小伙伴对SDK不是很熟悉 下载下来不知道怎么跑在系统里 特此写下这篇文章记载一下JavaDemo的初始化准备 初始化Windows SDK Java环境 https blog csdn net
  • 使用IDEA如何对Java项目进行打包

    我们开发的项目大部分都使用jar包交付 那么如何使用IDEA打jar包呢 下面我们写一个最简单的打包方式 1 首先先把项目编译一下 点击顶部工具栏 build gt build project 2 打包项目 点击file 选择此项 按以下顺
  • Docker是什么?它的优点与作用是什么?我们为什么使用docker?

    文章目录 1 我们为什么使用Docker 2 Docker是什么 xff1f 2 1 镜像 概念 xff1a 复制的程序 2 2 容器 概念 xff1a 集装箱 2 3 仓库 概念 xff1a 存放镜像的地方 3 Docker的作用 xff
  • 使用Java-Maven操作MongoDB增删改查

    文章目录 1 环境配置2 单元测试2 1 查询记录2 2 新增记录2 3 更新记录2 4 删除记录 1 环境配置 pom xml 依赖 span class token tag span class token tag span class
  • Centos7-Docker搭建私有仓库与配置

    文章目录 1 私有仓库搭建与配置2 docker 客户端配置3 镜像上传至私有仓库4 客户端拉取镜像 1 私有仓库搭建与配置 搭建私有仓库的作用是为了使用docker的镜像 把开发环境 测试环境 运维环境统一软件版本 使开发测试过程中不会出
  • centos7-Docker {:plugins_not_found, [:“rabbitmq_delayed_message_exchange-XXX.ez“]}

    文章目录 1 下载插件2 Docker 导入插件3 启动插件错误代码 1 下载插件 github 插件下载 最好下载 3 9版本 版本太高不支持 下载成功后上传到服务器中 2 Docker 导入插件 使用命令把插件上传到Docker容器的p
  • springboot集成RabbitMQ---延迟队列---TTL(队列)---死信队列

    文章目录 1 延迟队列1 1 插件下载1 2 延迟队列环境配置1 3 生产者 消费者1 4 结果验证 2 TTL队列2 1 封装TTL队列工具类2 2 结果验证2 3 单条消息设置TTL2 4 结果验证 3 死信队列3 1 死信从何而来3
  • SpringBoot整合RabbitMq实现ACK机制--消息回退机制--消息确认机制

    文章目录 1 环境配置2 RabbitMq配置2 1 消息发送确认机制2 2 消息投递确认机制2 3 ACK消息签收机制 3 消息生产者 1 环境配置 pom xml span class token tag span class toke

随机推荐