项目实战|基于STM32的无刷电机开环控制
电机转动的本质是在磁场的作用下,转子绕定子运动,从而带动整个机械结构转动。从有无电刷,我们可以将电机分为:有刷电机和无刷电机;从供电方式,我们又可以将电机分为直流电机和交流电机。我最近学习的内容主要集中于无刷直流电机部分。
无刷电机概述
无刷直流电机(Brushless Direct Current Motor,简称BLDCM)由电动机主体和驱动器组成, 是一种典型的机电一体化产品。 无刷电机是指无电刷和换向器 (或集电环)的电机,又称无换向器电机。这是模型中除了有刷电机以外用的最多的一种电机, 无刷直流电机不使用机械的电刷装置,采用方波自控式永磁同步电机,与有刷电机相比,它将转子和定子交换, 即无刷电机中使用电枢绕组作为定子,使用钕铁硼的永磁材料作为转子,以霍尔传感器取代碳刷换向器, 性能上相较一般的传统直流电机有很大优势。
无刷电机的特点
有刷电机示意图如下所示:
无刷电机示意图如下所示:
无刷直流电机(EN: Brushless Direct Current Motor),克服了有刷直流电机的先天性缺陷,以电子换向器取代了机械换向器,所以无刷直流电机既具有直流电机良好的调速性能等特点,又具有交流电机结构简单、无换向火花、运行可靠和易于维护等优点。无刷直流电机的实质是直流电源输入,采用电子逆变器将直流电转换为交流电,有转子位置反馈的三相交流永磁同步电机。性能上相较一般的传统直流电机有很大优势,是当今最理想的调速电机。
无刷电机的KV值及转速
无刷电机的实际转速=KV值*工作电压。KV的物理意义,就是无刷电机在1V工作电压下每分钟的转速。KV值与匝数呈反比例关系。
注意:无刷直流电机的转速与电压呈正比关系,电机的转速会随着电压上升而线性上升。
无刷电机的工作原理
无刷电机的本质是转子、定子因为磁场的原因发生吸引、排斥,从而使转子绕着定子发生转动,从而带动电机整体移动。无刷直流电机相数多为三相,常使用“三相星形联结的二二导通方式”。
在A端上电源正极,在B端接电源负极,那么可以在线圈A和B中可以产生如图所示的磁场,因为磁场强度是矢量, 所以由磁场BB和BA可以得到合成磁场B。此时转子就会保持在图中方向。
而当A、B、C三相按一定顺序通电时,会出现以下情况:
通过以上循环,我们就能实现无刷电机(转子)的转动。
提到循环通电,我们必须使用一种叫做三相六臂全桥的驱动电路,利用MOS管的导通与关闭,我们就能实现对不同相的供电与断电。其原理图如下所示:
控制方法概述
控制BLDC时,我们需要知道转子磁极的位置,从而根据检测的位置进行换相通电。但由于项目需要,我们使用更高精度的编码器对电机位置进行反馈,故我们首先使用开环控制(无霍尔传感器/无反电动势的方法)进行测试。
那么具体怎么实现开环的控制呢,和杨工讨论后,得到了使用PWM波+死区取反的方式来进行MOS管的控制,进而实现纯开环的电机控制。
通过改变单片机的定时器周期来调整频率进而控制速度。主要采用三相六通道的PWM波形式来进行电机驱动,我们的PWM波采取的是SPWM波的形式。所谓SPWM波即通过脉冲调制而使方波变为类正弦波,这样做是为了使得电机转动更均匀。
硬件设计
我们使用STM32CubeMX进行项目构建,这是为了避免写配置和使能代码的麻烦。但需要注意的是HAL库尽管会对配置代码进行自动生成,但通道使能以及功能开启还是需要自己用代码实现。
此外,HAL库最大的特点之一是中断服务函数的多样,具体请查看参考文献。
引脚接口如上图所示,其中高级定时器TIM1的CH1,CH2,CH3(含对应的N)通道用于控制三相电机的三相;TIM3的CH1和CH2通道用于接收编码器传来的信号;ENC_Z是开启了外部中断的普通IO口,用于接收编码器的Z相零点信号。而对于LED灯等其它硬件部分,为节省篇幅按下不表。
关键代码
代码整体思路为:LED_1在开机后长亮,当电机换相时,LED_2闪烁两次。通过按两个按键来调节电机转速,KEY_1增速,KEY_2减速。LED和KEY的配置略去,在这里仅讨论电机控制。
控制电机采用的是TIM定时器的PWM生成模式,通过对三相输出相位角相差120°的PWM波来使电机能够按照我们的需求进行平稳转动。
关于TIM1的配置信息如下表所示:
配置项 | 配置信息 |
---|---|
Prescaler | 0 |
Counter Mode | Center Aligned Mode 1 |
Counter Period | 2400 |
Dead Time | 1 |
PWM Pulse | 900 |
CH4 Pulse | 1 |
在前文中,我们提到我们使用的是TIM1的CH1、CH2、CH3三个通道控制电机,那么为什么还设置了CH4 Pulse呢?这是因为我们需要一个时序信号来对三个通道进行协调,如果没有CH4的时序,我们很难恰好让3个通道按照120°相位差输出PWM波。
首先我们需要一个函数来改变定时器一个周期的脉冲数:
static void TIM_SetPeriod(TIM_TypeDef *TIMx, float myfreq){TIMx -> ARR = (uint16_t)(72000000/300/myfreq);
}
其中,myfreq
通过调节PWM波的频率来调节电机转速。
我们看看最重要的PWM中断服务函数:
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim){static uint16_t temp = 0;if(htim -> Instance == TIM1){if(htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_4){if(temp < 100){TIM_SetCompare1(TIM1,(uint16_t)(period_percent*(sin_val[temp])));TIM_SetCompare2(TIM1,(uint16_t)(period_percent*(sin_val[temp+200])));TIM_SetCompare3(TIM1,(uint16_t)(period_percent*(sin_val[temp+100])));}else if(temp < 200){TIM_SetCompare1(TIM1,(uint16_t)(period_percent*(sin_val[temp])));TIM_SetCompare2(TIM1,(uint16_t)(period_percent*(sin_val[temp-100])));TIM_SetCompare3(TIM1,(uint16_t)(period_percent*(sin_val[temp+100])));}else{TIM_SetCompare1(TIM1,(uint16_t)(period_percent*(sin_val[temp])));TIM_SetCompare2(TIM1,(uint16_t)(period_percent*(sin_val[temp-100])));TIM_SetCompare3(TIM1,(uint16_t)(period_percent*(sin_val[temp-200])));}temp++;if(temp >= 300) temp = 0;}}
}
其中的TIM_SetComparex(x=1,2,3)
是我们自己定义的函数,如下:
static void TIM_SetCompare1(TIM_TypeDef *TIMx, uint16_t Compare){if(TIMx == TIM1) TIM1 -> CCR1 = Compare;if(TIMx == TIM2) TIM2 -> CCR1 = Compare;if(TIMx == TIM3) TIM3 -> CCR1 = Compare;
}
此外,sin_val[300]
是一个正弦转化数组,即通过这个数组的配置,外加TIM_SetComparex
函数,我们就可以将PWM方波转化为SPWM正弦波。(当然,这里的转化为正弦波指的是通过PWM占空比的调节,使得数字信号在一个周期内可以被当作模拟正弦信号)
period_percent
的计算公式如下所示:period_percent = (72000000.0/300.0)/myfreq/32678.0
。该公式计算的是一个周期内某一时刻的PWM占空比。
如何得到sin_val[300]
内的数值呢?我们可以通过数学方法进行计算:即将一个周期的sin函数
均分为300个点,算出每个点的值与幅值的比,再乘以一个系数,即可得到sin_val[300]
内的数值。当然,我们还可以下载网上的一些小工具来直接得到参数值,比如这个:sin_cal。
至此,大部分控制代码都已经完成了,但对于HAL库来说,它会帮助我们使能GPIO口、完善相关参数配置,但不会帮我们开启功能。所以我们如果要开启功能,需要进行以下操作:
HAL_TIM_Base_Start(&htim1); //开启TIM基础功能HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); //开启各通道的PWM输出功能
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1); //开启各N通道的PWM输出功能
HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_3);HAL_TIM_PWM_Start_IT(&htim1,TIM_CHANNEL_4); //开启通道4的PWM中断
最后,补上一个令电机暂停(停止)的函数,该方法是让电机缓停止,即不会立刻停止(这样可能会损坏电机),而是不给电,让其自动停止。
一些补充知识
1、预装载寄存器的作用:需要用户修改的预装数据立即生效时将预装功能关闭,希望用户修改的数据不影响当前周期的计数或波形输出时,我们就打开其预装功能。
2、中央对齐模式1:计数器交替地向上和向下计数。输出比较中断标志位,只在计数器向下计数时被设置。
3、HAL_TIM_PWM_PulseFinishedCallback和HAL_TIM_PWM_PulseElapsedCallback的区别:前者是比较中断触发的中断函数,后者是一个时钟周期结束后触发的中断函数。
待解决的问题
1、电机缓启动的代码还没有写;
2、电机速度调整还没有实现;
3、电机闭环控制还没有实现。
参考文献
1、野火 - 电机开发应用实战指南
2、搜狐 - 一文带你读懂什么是无刷电机
3、知乎 - STM32定时器比较输出话题
4、CSDN - 定时器的PWM设置详解
5、CSDN - GPIO的输入输出模式
6、博客园 - TIM计数器及中断开启
7、博客园 - 生成两路互补SPWM波
项目实战|基于STM32的无刷电机开环控制相关推荐
- python3语音识别模块_『开源项目』基于STM32的智能垃圾桶之语音识别
大家好,我是『芯知识学堂』的SingleYork,前面给大家简单介绍了『开源项目』基于STM32的智能垃圾桶之成员简介,相信有很多小伙伴都已经忍不住跃跃欲试了,别着急,从这一篇开始,笔者将会带领大家一 ...
- stm32语音识别文字显示_『开源项目』基于STM32的智能垃圾桶之语音识别
大家好,我是『芯知识学堂』的SingleYork,前面给大家简单介绍了『开源项目』基于STM32的智能垃圾桶之成员简介,相信有很多小伙伴都已经忍不住跃跃欲试了,别着急,从这一篇开始,笔者将会带领大家一 ...
- 自动化运维-----项目实战: 基于Ansible的云平台自动化运维系统
文章目录 项目实战: 基于Ansible的云平台自动化运维系统 一.项目介绍 1.项目介绍 2.项目背景 二.项目环境搭建 1.项目目录的配置 2.远程服务器虚拟环境的配置 3.MySQL数据库配置 ...
- 嵌入式项目实战——基于QT的视频监控系统设计(二)
嵌入式项目实战--基于QT的视频监控系统设计(二) 昨天我分享了关于QT的基本使用方法,掌握了这些基本的方法就可以设计一个简单的视频监控界面.下面我们开始分享完成这个嵌入式项目同样重要的知识点--UD ...
- 嵌入式项目实战——基于QT的视频监控系统设计(三)
嵌入式项目实战--基于QT的视频监控系统设计(三) 进入到五一假期第三天,继续我们的项目.本来五一假期还是想好好休息一下的,因为最近学习的状态不太好,刷题都没有思路了,但是身边的同学太卷了,不过我还是 ...
- 【STM32】【C】【嵌入式】分享一下我的项目经验--基于stm32桌面主从机械臂设计(二弹)
本文为原创文章,转载需要注明转载出处 前言:嵌入式开发是相比其他IT行业是比较难的行业,它不仅需要你去掌握软件的经验,还要去学习一些硬件的知识, 它是软件和硬件的一个粘合剂,起到一个至关重要的地位 下 ...
- 嵌入式项目实战——基于QT的视频监控系统设计(四)
嵌入式项目实战--基于QT的视频监控系统设计(四) 进入到五一假期的第四天,通过前三天的分享,相信你应该已经掌握了QT的基本使用.UDP网络编程.v4l2视频处理模块.多线程编程等基本的知识点.其实昨 ...
- 嵌入式项目实战——基于QT的视频监控系统设计(一)
嵌入式项目实战--基于QT的视频监控系统设计(一) 这个五一因为疫情,只能待在家里,想了想不如将我之前做的一个小的嵌入式的练习项目分享出来,供入门嵌入式的同学们学习.基于QT的视频监控系统设计虽然是个 ...
- 项目实战——基于计算机视觉的物体位姿定位及机械臂抓取(单目标定)
项目实战--基于计算机视觉的物体位姿定位及机械臂抓取(单目标定) 请各位读者朋友注意,这里面很多东西涉及到我的毕设,写作辛苦,请勿滥用,转载请务必注明出处! 单目标定主要分为两个部分, ...
最新文章
- 平头哥玄铁处理器Linux新版本,5大亮点速览
- [转]oracle设计数据库应选择正确的数据类型
- 【DP、线段树优化】琪露诺
- SpringBoot - 构建监控体系02_定义度量指标和 Actuator 端点
- Python 3.5将支持Async/Await异步编程
- DL之pix2pix:基于TF利用pix2pix模型对food_resized数据集实现Auto Color自动上色技术—训练测试过程全记录
- 【STM32】 keil软件工具--菜单详解
- 网络标准之:IANA定义的传输编码
- mysql 抓包乱码_mysql知识资源收集
- java面向对象基础代码_JAVA基础知识点之Java面向对象
- sql统计系统时间那一个月数量_关于BE00007图书借阅管理系统bug修复总结
- URAL 1820. Ural Steaks(数学啊 )
- 计算程序/函数运行时间
- 计算机网络管理师2级,计算机网络管理员(二级)操作技能考核试卷
- SBC音频编解码算法浅析
- SQL SERVER 实用教程(第四版) 实验 1-10 非标准答案
- 大厂软件测试流程完整版
- echarts 全国各省市地图切换展示
- 鸿蒙HarmonyOS应用开发系列 | 解读鸿蒙源码
- 用计算机怎么弹学猫叫,抖音我们一起学猫叫计算器谱分享
热门文章
- GitHub 标星 4.9k,李笑来开源的英语学习课
- 2020Java后端开发面试题总结(春招+秋招+社招)
- ES6 Math新增方法trunc() sign() cbrt()
- Kafka 发送消息 Idempotent -- Spring 整合
- 逍遥模拟器微信提示无法连接服务器,轻松解决夜神逍遥模拟器模拟器等模拟器无法连接问题...
- 51cto mysql下载_安装Mysql服务_大神程序员养成之路-Mysql数据库基础_MySQL视频-51CTO学院...
- win7怎么修改系统语言
- 债券收益率预测模型_ARIMA模型在中国移动债券收益预测中的应用
- 有利可图网_第一章:有利可图的项目手册
- python爬取千图网_python爬取lol官网英雄图片代码