已经做了半年的BLDC驱动器了,目前是做到了电流转速双闭环,期间遇到了很多很多问题,一个是资料难找,再加上公司要求使用CUBEMX,本身HAL库的资料也难找,难上加难啊,可能是用CUBEMX做出来的大佬们不愿意透漏吧,也可能是用CUBEMX的现在还是比较少,没有标准库那么多,所以很多人还是使用标准库。除此之外,在网上能够找到的资料大部分是直接根据霍尔状态来变换发波情况的,没有使用COM事件,或者是使用软件COM事件来切换发波通道,前一种使用外部中断来检测霍尔状态,我也写了相应的程序,测试了效果,也不错,与使用硬件COM事件效果差不多,但是如果使用软件COM事件,电流会比较大,使用软件COM事件还有直通的风险,甚至于在网上下载ST官方的BLDC驱动的例程,也是软件COM事件(也有可能是官方出了硬件COM事件的例程我没有找到),因为好多人做这个BLDC电机控制是为了以后的控制算法做准备,双闭环,FOC等等,第一步就没做好的话,后面的算法的质量更是无从谈起。现在刚好有空来写博客,把一些基础的资料心得整理一下,可能会有一些错误或者更好的方法,欢迎给我留言,毕竟我也是新手,还有很多需要学习。
看这篇文章的应该是需要使用CUBEMX来配置硬件COM事件的,所以一些基础的概念就不需要再阐述了,比如H桥,PWM这些东西。对于BLDC电机六步法的控制方式,我参考了这位大佬的博客:
https://blog.csdn.net/oXiaoXue123456789/article/details/80883145 写得还是非常详细的,我这里会引用一些他的图片,概念什么的(懒得找那些图片还有概念了)。
首先,对BLDC六步法的控制模式要有些理解,电路上的主要控制电路是三相逆变H桥,示意图如下:
六步法的基础是霍尔传感器,根据三个霍尔传感器的电平状态决定此时的发波状态,因为霍尔传感器的状态代表转子的位置。霍尔传感器的电平变化时固定的,一个周期内的变化如下:
而每个霍尔状态对应的发波情况对于一种电机时固定的,比如霍尔传感器A为低,B为高,C为高,此时对应一种发波情况,也就是说三相H桥中,有一相发PWM,有一相完全打开,有一相不处理,将PWM输出关断。这里我为什么说对于一种电机时固定的呢?在实际的测试中,霍尔的变化顺序为 5,4,6,2,3,1(因为我的电路里加了反相器,因为顺序为5,1,3,2,6,4,这里的数字代表霍尔传感器的二进制组合状态,5也就是101,也就是A为1,B为0,C为1),实际电机旋转的时候是按照这个顺序变化,反转就反过来。假设使用60电机,规定546231为正转,513264为反转,那么使用57电机的时候,按照正方向的发波,刚好电机的旋转方向是反过来的,虽然说不影响控制,但是不统一,因为我后续还要加入反转检测(即电机霍尔的变化顺序没有按照预想的变化,通常发生在负载比较大或者堵转的时候),速度检测什么的,这样每种电机还要单独写反转检测这些东西,非常麻烦,我现在的做法是从刚开始的发波情况区分电机。
当时我们手上是使用的其他公司的驱动器,给他们技术打电话,问他们霍尔状态跟三相发波情况的对应表,他们技术说是网上都是统一的,可以直接参考,总监让我还是自己拿他们驱动器测量一下,严谨一些,测试过程也非常简单,就拿另外一块单片机,比如说霍尔状态是5的时候发个高电平,其余发低电平,实际测试出来的波形如下:
这里只是举个例子,最终我测量出来的57电机的关系表如下:
我们最后使用的电机时60电机,这个对应表有些变化,但是理解这个概念就行,也就是说,当霍尔信号是5的时候,U相要发PWM,V相上管关闭,下管导通,我用负来表示,W相把PWM输出关断,不管它。之前我也有些疑惑,上下管为什么要发互补PWM?我的理解是这样的:拿一个直流电机H桥举例:
要让电机顺时针转,也就要让电流方向让图中红 {MOD}线条的方向一样,那么有两种方法:
1.可以让左边上管发PWM,下管关闭,右边上管关闭,下管完全打开。这样是可以的。
2.可以使用互补PWM,也就是说,左边上管发PWM,下管发互补PWM,右边上管关闭,下管完全打开(也是配置为互补PWM,上管PWM=0,则下管就为100%打开),这样做有其优势,因为电流不会发生突变,当左边上管的PWM位于高电平的时候,电流方向是图中的方向,当PWM为低电平的时候,由于电机的感性作用,电流不会变为0,会产生一个反向电流,那么就可以通过下管的互补PWM将其消耗掉(此时左边下管是打开的),如果使用第一种方法,那么驱动电路将会发热,发热的功率也是比较大的。
讲完互补PWM,就要说一下COM事件是个什么东西了,在说这个之前需要理解一些寄存器的意思:
CCRx : 比较捕获寄存器,控制占空比
CCxE : PWM通道
CCxNE : 互补PWM通道
具体参考STM32参考手册的产生六步PWM章节,参考手册的描述是这样的:
看一下参考手册上的示意图:
我在图上加了标注,应该会好理解一点,就是理解这个预装载的功能,STM32控制哪个通道进行发波是由CCxE,CCxNE位决定的,控制PWM占空比是由CCRx位决定的。
上图是参考手册中对于预装载位的解释,CCxE,CCxNE,CCxM如果配置为预装载,那么只会在COM事件后更新,这一点非常重要,还有一点是,这个预装载位只对CCxE,CCxNE,CCxM位起作用,对于控制PWM的CCR位是不起作用的,CCR位会在更新事件后更改,一定要注意这两个的更新事件是不同的。
那么,在程序上,我们可以在COM中断里,检测此时的霍尔状态,然后配置下一步的发波通道,注意是下一步的。
STM32对于六步法控制BLDC中的霍尔传感器,有单独的定时器,一般是TIM2/3,这里我用的芯片是STM32F030,可以根据参考手册查到TIM1(互补PWM输出定时器)的主定时器对应表,如图:
之后就可以进行CUBEMX的TIM1的配置了。
在实际的程序中,虽然我在CUBEMX中打开了COM中断,刹车中断,但是实际测试却进不去中断回调函数,这个可能是HAL的BUG,也有可能是自己一些细节没注意,反正,我在程序里手动用寄存器又配置了一遍使能中断。当然,可以在系统生成的tim.c的文件中修改,也可以在自己程序的合适位置加入。我是在tim.c的HAL_TIM_MspPostInit函数中加入:
除此之外,也要配置预装载位,这个之前提到过,CUBEMX没有这个选项,要自己添加
至于PWM发波,那就很简单了:
直接更改CCR位就可以调节占空比。COM中断里面,就可以加入霍尔检测,然后配置通道以及PWM的占空比,对于占空比,可以在COM中断,也可以在更新中断中配置,因为CCR的值是在更新事件后变化的。要注意理清这个逻辑就可以,CCR的值会在下一个更新事件后发生改变,PWM通道会在COM事件之后改变。这个逻辑我之前也是理了很久。
TIM1配置结束之后便是霍尔定时器了,我用的030里面霍尔定时器是TIM3,具体的配置,在参考手册的 与霍尔传感器接口一章:
以上是官方的解释与配置步骤,配置步骤讲得也是比较详细的,重要的是理解这个硬件触发COM事件的过程,官方给的示意图是这样的:
我在图中加了标注,看起来还是比较直观的,那么在实际的使用中,会有一个问题,那也就是,假如电机转得很慢,或者不转的情况下,那TIM3因为CNT一直在计数,一直在产生比较捕获事件,也就是说,每个周期都会产生一个比较捕获事件,那每个周期都会产生一个COM时间,如果产生COM事件的频率比电机霍尔信号变化的频率还有快,那不就有问题了吗,这里,官方说,建议把TIM3的周期设置得长一点,保证电机转得最慢的情况下,霍尔变化的周期也比TIM3的周期短,我宁愿相信ST官方在其他地方说了这个问题的标准解决办法,不然这种解决方法也太坑了。。。。但是我依然没有找到官方给出的标准解决办法。
这种问题,在思考之后,有几种解决办法:
1. 在从定时器TIM1的触发或者COM中断中,检测CNT的值,如果此时CNT的值马上就要溢出了,就把它清零掉,这种方法比较麻烦,毕竟开那么多高频率的中断是不太好的,当然,我试了这种方法,也还好吧,但不建议使用;
2. 在霍尔发生变化之后再开启CNT计数,其余时间关掉,这种方法我没有试过,配置比较麻烦;
3. 将TIM3配置为单脉冲模式,每次只发一个脉冲,在下一次霍尔变化时,再触发TIM3发送一个脉冲,我们实际也是采用的这种方法,效果很不错。
接线来就是程序配置环节了,按照参考手册一步一步配置当然是可以的,不过CUBEMX将其中的一部分配置集合了起来,相对便利了一些,但是有些特殊配置还是要自己来,我们现在就是要把TIM3配置为霍尔定时器模式+单脉冲模式。如图:
在程序中,要使能一下霍尔定时器才可以使用。
然后是单脉冲模式的配置,对单脉冲模式的配置,官方手册写了一个例子:
想再仔细看的话,自己去看参考手册吧,按照这个例子,再结合自己的实际情况配置单脉冲模式,仅仅是CUBEMX上的单脉冲模式打个√是不能用的。配置完硬件COM事件之后,还有一个问题,那就是启动问题,在启动时是无法触发硬件COM事件的,因此在启动时可以使用一次软件COM事件。