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

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

一、硬件设计

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.kler.cn/news/17382.html

相关文章:

  • 内存越界是否一定会导致程序崩溃吗?详解内存越界
  • CUDA下载,以及下载GPU版本的pytorch
  • JAVA基于Springboot框架的停车场管理系统开发实践和实现【附源码】
  • DP动态规划
  • 1.rabbitMQ介绍
  • JavaScript闭包的基本原理和应用场景
  • 人的全面发展评价指标体系—基于相关-主成分分析构建
  • 2000-2019年30省研发资本存量(含计算过程和原始数据)
  • 大数据Doris(八):Broker部署和集群启停脚本
  • 高效学习方法和工具推荐,让你事半功倍!
  • clickhouse里的数组数据类型与相关使用介绍
  • 【C++复习1】程序结构和C++的工作原理
  • Java程序设计入门教程--数组
  • 小球下落(dropping balls)uva679
  • go 打包文件夹成zip文件
  • Envoy控制面实践
  • 漫画 | Linux之父:财务自由以后,我失眠了!
  • 华为OD机试 - 整理扑克牌(Python)
  • [计算机图形学]光场,颜色与感知(前瞻预习/复习回顾)
  • 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,基于 CentOS 7 构建 LVS-DR 群集
  • springboot 集成 shardingSphere 加mybatisplus 自带增加 分页查询 和源代码包 分库分表 单库 分表 使用雪花算法id
  • node.js 处理路径问题
  • VR与AR:哪个有更大的潜力改变未来?
  • 今天面了个字节跳动拿35K出来的,真是砂纸擦屁股,给我露了一手啊
  • Skywalking
  • gtest之高级主题
  • Spring常用注解总结
  • PAT A1024 Palindromic Number
  • Java对象的创建方式以及对象的引用
  • 【Elsevier】中科院2区TOP, 高被引119篇, 稳定检索22年, 1周可见刊,5月15截稿~