完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
大家好,我是小政。本篇文章我将针对平衡小车中的电机控制进行详细的讲解,驱动一个电机最重要的就是给它一个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的频率,并通过改变占空比调节电机的速度。 特点:
电机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 if(*motoB>PWM_MAX)*motoB=PWM_MAX; if(*motoB 3)绝对值函数(非常通用,建议保存!!) 入口参数:常规变量 通过与0比较,大于0则返回不变的值,小于0则返回相反的值。 int GFP_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,GFP_abs(moto1)); //1.研究正负号,对应正反转 if(moto2>0) Bin1=1,Bin2=0; else Bin1=0,Bin2=1; //2.研究PWM值 TIM_SetCompare4(TIM1,GFP_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 GFP_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软件编程的讲解,文章中出现错误或者小伙伴对以上内容有所疑问,欢迎大家在评论区留言,小政看到后会尽快回复大家! |
|
|
|
只有小组成员才能发言,加入小组>>
2431 浏览 0 评论
9083 浏览 4 评论
36748 浏览 19 评论
5021 浏览 0 评论
24707 浏览 34 评论
1513浏览 2评论
1731浏览 1评论
2171浏览 1评论
1539浏览 0评论
510浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 19:42 , Processed in 1.584989 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号