找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

无感FOC代码: 调试简单,起转顺利

  [复制链接]
61#
 楼主| Angus 发表于 2024-9-23 11:33:55 | 显示全部楼层
本帖最后由 Angus 于 2024-10-2 21:09 编辑

代码的总体架构就是main() 里的主循环 + 两个中断,这里介绍一下这三部分之间的关系或相互之间的数据通信



每个PWM 周期产生一次 ADC 中断,转电机的代码主要在 ADC 中断里,包括电流 PI 计算。"电流 PI 运算"的电流设定值来至 SysTick 中断里"转速 PI 计算"的计算结果(同步转时), 或ADC 中断里自己决定电流设定值大小(启动时)。

SysTick 中断代码里,用转速设定值和实际值,做转速 PI 计算求出电流设定值 Iq_set_f12,Id_set_f12 由 ADC 中断代码用。既然这个全局变量,只有在同步转时 ADC 中断代码才用到,不同步时,就不做这个转速 PI 计算了,详见 SysTick 中断代码。

在 ADC 中断里,状态机的转变如下图,状态0(关功率管停转状态)不会变成其它状态,如果需要启动(转速设定值 RPM_Set >0) 要在 main() 主循环里判断,转变为状态2(静止状态启动)或状态6(顺风转时启动)



main() 主循环里,除了启动前判断一下是否已顺风转,还会做一件事:判断如果启动时出现 RPM_Set <=0, 就是又不想启动了,那就直接变状态1、立即停止启动,不必再等超时了。
回复 支持 反对

使用道具 举报

62#
 楼主| Angus 发表于 2025-1-13 11:18:13 | 显示全部楼层

回复 支持 反对

使用道具 举报

63#
 楼主| Angus 发表于 2025-3-5 15:02:04 | 显示全部楼层
本帖最后由 Angus 于 2025-3-17 22:11 编辑

转速控制 ,涉及到以下几个变量

RpmMechanical_Set : UART转速指令、或由旋钮获得的机械转速值

RPM_Command :  转速指令对应的电转速,但是,若Stop_Runing 非0(有异常)此值等0

RPM_Set_Target : 控制加减速的转速设定值,此变量慢慢增加或慢慢减小,直到等于RPM_Command,范围 0~Max

RPM_Set   :   此变量基本= RPM_Set_Target,  只是范围 Min ~ Max,停转时此值是负值,是为了加快转速PI 运算结果的电流值下降

停转时,若想降速受控,慢慢降速,就让 RPM_Command =0,电流慢慢下降。降速过程保持着同步。
停转时,若让RPM_Set_Target=0,则电流立即=0,风机会自由降速,降速过程仍保持着同步。水泵降速很快。
若让状态变量 Motor_Status =0,下个PWM 周期就关功率管,电机自由停转,降速过程不保持同步。
回复 支持 反对

使用道具 举报

64#
 楼主| Angus 发表于 2025-3-12 16:58:47 | 显示全部楼层
本帖最后由 Angus 于 2025-6-5 17:22 编辑

缺相时,电流等于0,似乎缺相不难检测出,可做起来并不容易。
正常转动时,角度=0或180度时,相电流等于0,所以不能检测到电流=0就认为是缺相。如果检测到电流=0持续一段时间才认为是缺相,则在确定缺相前,可能电机已无法正常转动,可能因观测器数据错误已关功率管了。

启动期间三相的电流差异较大,缺相的条件很难确定。若以长时间电流较小为条件,则检测多长时间合适呢?不容易确定。

实际测试还发现,断线的那相,电流ADC 数据异常波动,波动幅度已超过了轻载、低速转动的电流。 如果设置一个电流门限,低于此门限就认为是缺相,电流判断门限若设置高了,轻载低速时会误判为缺相。若门限低了,真缺相又会判断不出来




我们最终确定的办法是,启动前在 240 度通电,通电时间参考 L/R,一般几个毫秒就可以。这时电流经 C 相流向 AB 相, 三相都有电流,AB 相电流是 C 相的一半。如果有一相电流比设定电流小一半以上, 置位一个标志,可能缺相了。 继续启动, 如果后面启动成功了,就不认为是缺相,清除标志(310行)。如果后面启动失败了,才确定是缺相(285行),这样就减少了误判。





回复 支持 反对

使用道具 举报

65#
 楼主| Angus 发表于 2025-3-14 09:16:23 | 显示全部楼层
本帖最后由 Angus 于 2025-5-14 22:00 编辑
游客 58.49.24.x 发表于 2025-3-14 08:34
思路好。不过有另外的问题,假如没有缺相,启动失败也发生了,那这时怎么判断是什么故障? ...

如果没缺相,标志 TempFlag_Open 不会写成非0,一次启动失败,会停一秒左右,再次启动。如果电机卡住了根本转不动,FailCnt 失败计数,多次失败就不再启动了(上图中 286行),需人工干预,不会报缺相故障,报多次启动失败故障。

正常情况一次就能启动成功。若负载很重,偶尔会失败一次,第二次能启动成功。
回复 支持 反对

使用道具 举报

66#
 楼主| Angus 发表于 2025-4-12 14:30:40 | 显示全部楼层
本帖最后由 Angus 于 2025-6-26 10:01 编辑

V26版,优化了启动逻辑,提速逻辑和缺相检测,并且把ADC 限流改为周期性检测和阶梯性报警。
如何做到重载启动顺利,轻载启动转速又不上冲呢? 方法说出来其实很简单:限压。 说出这两个字有人立马就明白了,很多事就是一层窗户纸。

电机的转速与电压成正比,300V 电压轻载时若有一万转,启动时限压 30V 转速就不会高于一千转。重载时转速稍低一点,900转左右,不会太低。

以 V26 代码为例,启动时,在状态5 代码中, 设定限压值再跳转去状态3或状态4,开始电流拖动。一旦转起来,反电势会让实际电流下降。电流实际值可能远小于设定值,即控制处于输出饱和状态。变同步时再做调整。



回复 支持 反对

使用道具 举报

67#
 楼主| Angus 发表于 2025-5-14 22:29:25 | 显示全部楼层
本帖最后由 Angus 于 2025-6-26 09:59 编辑

转速的计算和控制一。

转速的计算: RPM 转速 = 转过的角度/一圈角度/时间,再换算成一分钟转过的圈数。

有些应用,转动是不均匀的,比如活塞式压缩机,压缩时转速变慢,回程时转速快, 计算转速要在一个机械周期内求平均。
如下图一个机械周期有四个电周期。

为了加快转速控制的响应,每转过一个扇区,我们就对前面一个机械周期——24个扇区,求平均转速,所以要保存前面24个扇区边界的角度和时间,即至少25组数据。

代码中结构体数组 Section_data[SECTION_RPM_AVERAGE +2],保存跨过扇区边界时的角度的时间,SECTION_RPM_AVERAGE 是一个机械周期的扇区数 。


上图 N = 24 个扇区一个机械周期,如果转动在宏观上是平稳的,第 N 个扇区转动时间,将等于第 N+1个扇区的时间。这样可更快发现转速的变化,转速控制的响应将更快,这个留给有兴趣的人去测试。代码中保留了 N+1 个扇区的边界数据,即 N+2 组数据。
每次 PWM 检查一次,若跨过扇区边界就记录一下角度和PWM计数值,角度不会刚好是60度。时间用 PWM 周期个数再乘 PWM 一个周期的时间。







回复 支持 反对

使用道具 举报

68#
 楼主| Angus 发表于 2025-5-15 09:59:49 | 显示全部楼层
本帖最后由 Angus 于 2025-6-26 09:58 编辑

转速的计算和控制二

启动时,至少转过 N 个扇区,转速的计算才正确。在转速正确之前,不能做转速 PI 运算。每计算一次转速,变量 Do_Spd_PI 就加1。启动时赋值 Do_Spd_PI = -N-3;  转过一个扇区边界后 Do_Spd_PI = -N-2 ;  算是起点,再转过一个扇区边界Do_Spd_PI= -N-1; 就有了一个扇区前后两个边界的角度和时间,Do_Spd_PI= -2 时就有了 N 个扇区两边的角度和时间,就可计算出正确的转速了。


启动时不能做转速 PI 控制,也不能让转速设定值一直往上增加,所以代码中让转速设定值变量 RPM_Set_Target 一直等于测量转速。
启动后只有转到 Do_Spd_PI = -2 时,转速才正确,前面虽转速数据不对,让RPM_Set_Target = 测量转速,也无妨,因不做转速 PI 控制。 Do_Spd_PI = -1 以后就可以做转速 PI 控制了。



另一方面,启动阶段未变同步转动时 Motor_Status & 0x10) = 0,也不能做转速 PI 控制,也不能让设定转速一直往上增加。
启动时,是先 Do_Spd_PI 增加到0、还是先变同步转,不一定。

回复 支持 反对

使用道具 举报

69#
 楼主| Angus 发表于 2025-5-15 11:11:23 | 显示全部楼层
本帖最后由 Angus 于 2025-6-26 09:55 编辑

转速的计算和控制三。

同步转动时,测量转速值未更新也不做转速 PI 。在转一扇区时间、长于转速 PI 计算周期后,多次执行转速 PI 函数做一次 PI 运算,这相当于减小了积分系数,即随着转速降低,转速积分系数跟着降低。


如果不想让积分系数一直降低,就把变量 WaitCount 利用起来,当转速低到一定程度,Do_Spd_PI 一直不更新,而 WaitCount 已加到上限,也做一次转速 PI 运算。就得到了如下转速积分系数曲线:

代码中 WaitCount 计数到 6 做完一次 PI 运算,让 Do_Spd_PI = -1,目的是如果转速又立即更新了,Do_Spd_PI=0而不是=1,  不会很快又做一次转速 PI 运算。




回复 支持 反对

使用道具 举报

70#
 楼主| Angus 发表于 2025-5-16 13:40:03 | 显示全部楼层
本帖最后由 Angus 于 2025-5-17 10:55 编辑
游客 58.49.24.x 发表于 2025-5-16 08:35
这里有个疑问,限压后,轻载能满足启动的电压电流要求,重载时,电压会不会不够用?毕竟负载不同,需要的 ...

限压多少,应按重载测试的效果确定,轻载启动稍快一点,依然很平稳,转速不会冲到很快。

限压带来的最大好处,是启动代码变得简单了,调整启动特性容易了。
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU