牛卧堂MCU技术交流

标题: 15万转无感FOC: 高压风机水泵吸尘器,冰箱空调压缩机 [打印本页]

作者: Angus    时间: 2016-8-10 16:46
标题: 15万转无感FOC: 高压风机水泵吸尘器,冰箱空调压缩机
本帖最后由 Angus 于 2024-11-21 10:00 编辑

参考原理图 M451_FOC.pdf (39.23 KB, 下载次数: 4217) , 图中第三相驱动和前两相一样,省略, 省一页图纸。
M451无感FOC吸尘器在10万转时,电流钳测的电流波形

每个PWM周期的计算耗时小于20us。如果 PWM=30KHz/周期33us,转速就可跑到 15万转。

启转快,同步快,代码精简到8K


顺风启转,直接同步


让电流设定值突变,电流响应快、并且无超调


有感FOC的IAR工程代码: M451_SVPWM.zip (1.57 MB, 下载次数: 4740)
运行此代码,不接电机,在PWM0_0, PWM0_2, PWM0_4 引脚接 10K/1uF 阻容后就可测到如下波形


带详细中文注释的无感 FOC 代码 M451_FOC_V23_Nu-LVMDM.zip (826.7 KB, 下载次数: 2327) ,量产后可开放 M4_SVPWM.lib。
1>,在 DQ 坐标轴做的磁链观测器。并充份利用了 M4 内核的 DSP 指令加快运算。
2>,有电流超前角控制,根据电机特性可实现 MTPA 控制或弱磁恒功率控制。
3>,三闭环控制,转速闭环外,有功率闭环控制,可精准控制功率值。
4>,有加速度控制,可方便实现慢加速,或快加速过程。
5>,积分分离法 PI 抗饱和运算。
6>,一个宏定义选择用 I/F 起转,还是V/F 起转。

每一行代码都反复检查和测试,我们精雕细琢,只为性能卓越

此代码效果的视频 M451_Video.zip (32.33 MB, 下载次数: 269)
电机参数不同或电路不同时,代码修改说明 M451无感FOC 代码说明.pdf (1.88 MB, 下载次数: 2062)

PWM 触发ADC中断代码流程:  读取电流 =>迭代运算、估算位置=>算三路PWM 占空比写入寄存器

  
过调制输出电压。 过调制可提高电压利用率


技术支持电话
新唐电子科技(上海)有限公司   021 - 62365999















M451_FOC基本原理.pdf

1.73 MB, 下载次数: 3225


作者: Uwen    时间: 2016-11-30 17:03
Angus 发表于 2016-11-27 21:41
目前只做到按霍尔位置算电压失量,还没做到电流失量控制那一步

hello:
        读了一下程序,发现有几个值没整清楚。
Voltage_dc = 100000 ;                                    // PWM 周期是 4000, 母线数值太大无意义
Voltage_q  =  40000 ;                                    // Vd,Vq 范围 -65535 ~ 65535
Voltage_d  =   1000 ;                                    // Vq,Vd 的模超母线的 0.577 倍波形会消顶
这几个值,如果电机不一样,输入电压有变化,怎么选择?有怎么样的算法?有例程吗? 谢谢!!!
作者: Angus    时间: 2016-12-3 12:05
本帖最后由 Angus 于 2017-3-14 22:11 编辑

看一下 FOC 控制框图,系统控制的输入量是 Id,Iq 的设定值。Vd,Vq 是 PI 计算出来的理想值,再由 Vd,Vq算出 PWM 的占空比。
若想提高调节精度,一方面要增大 PWM 周期,PWM 周期为 4000 时,调节1,电压只调整了 1/4000。另一方面要提高由 Vd, Vq 计算 PWM 的精度。采用定点数,只能提高 Vd, Vq 的数值,而 Vd,Vq 的最大取值受限于母线的最大取值。
   由此可见,母线数值选的越大,Vd,Vq 被允许的范围就越大,计算精度就越高。母线最大数值若超过 PWM 周期的四倍以上,电压的舍入误差已小于 PWM 所能达到的精度的 1/4,PWM 已无法完成如此精细的电压调节。
作者: rete0786    时间: 2017-3-14 13:32
哈哈,好东西,赞一个
作者: arm_nuedu    时间: 2017-7-27 20:39
PD->MODE      = 0x00000400 ;               
  SYS->GPD_MFPL = SYS_GPD_MFPL_PD0MFP_UART0_RXD
                | SYS_GPD_MFPL_PD1MFP_UART0_TXD  ;

还有这个PD0 PD1,不是该0X0000 0004
作者: Angus    时间: 2017-7-27 21:46
arm_nuedu 发表于 2017-7-27 20:39
PD->MODE      = 0x00000400 ;               
  SYS->GPD_MFPL = SYS_GPD_MFPL_PD0MFP_UART0_RXD
        ...

代码中 PD->MODE = 0 ;
PD0 配置为 RXD 自动为输入,PD1 配置为 TXD 自动为 CMOS 输出, PD->MODE 的值已无效  
作者: arm_nuedu    时间: 2017-7-28 11:48
哦哦,明白了,谢谢
作者: xiaoxiao2013    时间: 2018-11-20 13:57
请问,你启转那个图片是怎么启动的?是无感运行?看图上没有开环切闭环,是不是这样?你那个位置估算器是常用的,难实现这样的效果
作者: Angus    时间: 2020-5-29 14:09
本帖最后由 Angus 于 2020-5-29 14:12 编辑
游客 115.226.132.x 发表于 2020-5-29 10:36
请问楼主:在做无感位置估算器中,需要用到Valpha和Vbeta,这两个值是怎么得到的,提供的原理图中只有两相 ...

电机中的三组线圈在圆周上呈120度安放,三相通电后,合成电压的方向可以是360度的任一方向,所以就用复数表示,Valpha  + jVbeta

所以Valpha, Vbeta 是电压失量的实部和虚部,是计算的中间变量。

作者: 匿名    时间: 2022-1-10 21:39
调速旋钮刚好在最小启转值附近时,可能因数据抖动,造成启转、停转、启转、停转现像。为了防止这种现象,将调速旋钮值,做回差处理,如下图。

未转时,旋钮从0向上调,超过最小值的3/4, 到最小值之间,都算是最小值。
转动时,旅钮从上向下调,高于最小值的一半,到最小值之间,都算最小值。

未转时,旋钮调到3/4处,就会启转,这时,旋钮值上下抖动一点,转速设定值保持最小值不变。
实现代码,如下:


作者: a20084666    时间: 2022-1-15 14:40
最近出的都是干货
作者: Angus    时间: 2022-1-20 14:35
本帖最后由 Angus 于 2024-9-15 16:10 编辑

这里讲一下代码中的 PI 运算。

模拟 PID 运算公式 :

去掉微分运算,再把公式离散化,公式变为:


采用增量式算法:


下面是转速 PI 运算的代码
代码 733 行:增量 = Kp*[本次误差 - 上次误差] + Ki * 本次误差
代码 734 行,temp32 = U(n-1) + 增量。
736~739行是抗饱和运算
741 ~ 742行,计算结果 temp32 做限幅后,再赋值给电流设定值变量 Is_set_f12

  



作者: Angus    时间: 2022-1-23 21:36
本帖最后由 Angus 于 2024-9-12 13:41 编辑

这里讲一下 Clark 变换

求 I_alpha, I_beta,  就是求电流向量的实部和虚部。A相在0度,B相在120度,C相在-120度,三个电流写成复数形式分别为


求三个电流的“失量和” 。 三相电流的“标量和=0“,即Ia+Ib+Ic = 0,这个不用求。


因为在下MOS 导通时测电流,显然下MOS导通时间长时,电流ADC 受PWM 开关影响就小,值相对准确一些。
如果 C 相下 MOS 导通时间短、就用 Ia 和 Ib 计算电流向量, Ic = -Ia-Ib 代入向量求和公式,得到

消去 Ia 或 Ib 的公式,请读者自己推导

等幅变换中电流向量若是 I,  则对应相电流峰值是 I*2/3。所以上式求出的电流向量,乘2/3后才与控制量对应,  这样公式就变成了

上式这个电流向量的模,正好与相电流的峰值,数值上相等。
下面来看代码,
181~189行,按扇区,选择下MOS导通时间长的两相, 求I_alpha, I_beta,为了减小计算误差先增加小数,数值乘8
191行,1/3 的开方=0.57735 =18919/32768, 所以乘18919再右移15位就是乘1/3的开方,右移小了3位,等于是把结果乘了8


执行完191行后,就求出了 I_alpha,I_beta 。接下来坐标变换求出了有3位小数的 Id 和 Iq 电流










作者: 匿名    时间: 2022-10-27 10:15
请楼主再给讲解一下变量标幺值,看不懂
作者: Angus    时间: 2022-10-27 21:48
本帖最后由 Angus 于 2024-9-12 14:00 编辑

电压的基准值是 0.1V。最大值是 16383,若超过此值, 乘4后大于等于65536做坐标旋转会溢出,即最大工作电压是 1638.3V。 在ADC中断里, 读出母线电压ADC值,就换计算出0.1V 的数值,然后赋给变量 V_BUS_0v1

具体代码如下:  母线电压,电路上是俩220K 串4K1电阻分压后到ADC 引脚,所以分压比 (220*2+4.1)/4.1,  12位ADC 参考电压是5V,  所以  ADC值换算成电压公式是:
电压 =   5V * ADC值 / 4096  再乘分压比(444.1/4.1), 这个公式右边再乘10 就是0.1V数值,简化后 = ADC值*5416/4096 。代码中 355 行, 加1024是四舍五入,右移 11位是除 2048,少除了2后面补上。

把当前电压 ADC 值看作 X,
457行是求出了 2X。
458行是 2X + 2Y,  这是母线电压的4倍, 成了 25mV 的数值,  用25mV数值去做 SVPWM计算,  哪怕工作电压不到10V,也有足够的计算精度。最大电压 1638.3V 的数据乘4后得65532, 坐标变换也不会溢出。
459行是 (2X + 2Y)/4 = (X+Y)/2, 这是一阶低通滤波 Y(n) = [Y(n-1) + X(n)]/2。


SVPWM 能输出的无失真相电压,最大值是 0.577倍的母线电压,再大, 就是削顶的正弦电压了。 263行,选择一个相电压上限值。
265行, 增加17位小数后,赋值给 Vq_Limit_f17,Vd_Limit_f17 (后缀 _f17 表示17位小数) 用于电流PI 运算结果的上限值。  电流PI 运算结果有17位小数,  电压上限在这里先增加17 小数,比在PI 运算结果限幅时再增加17位小数,节省代码。







作者: Angus    时间: 2022-10-27 22:01
本帖最后由 Angus 于 2023-2-19 11:09 编辑

电流的基准是ADC 的值。一般电流ADC 数值较小,换算后会损失精度,所以不换算。ADC中断里,读出电流ADC 值乘 8 后再坐标旋转,求得 dq 轴电流赋给 Id_Measure_f3 ,Iq_Measure_f3 ,此处后缀 _f3,表示有 3 位小数。
在做电流PI 运算前,对直流量 Iq_Measure_f3 又做了一次滤波,并增加了一位小数赋值给 Iq_Meas_LPF_f4, 后缀 _f4 表示有 4位小数。


作者: 匿名    时间: 2022-10-28 15:00
十分感谢楼主解答,顺便请教一下这个代码有没有试过比较大的电感和电阻电机,如果一般冰箱压缩机的电阻有几欧姆到十几欧姆,电感几十到一百多mH,油烟机的风机电感和电阻也很大,惯量也大,可以试试效果。
作者: Angus    时间: 2022-10-28 21:26
本帖最后由 Angus 于 2022-10-29 12:44 编辑

下载代码后,不做改动,电感最大可到100mH,电阻最大可到500欧。
如果电感再大,可把电感除10后再赋值给Ld/Lq,然后把单位常量Unit_Magnify 也除10就可以。
目前我测试过的电机,电感最大的是220V的电机:50220/49220uH;电感最小的是航模电调用的一个小电机:11/9uH。

作者: 匿名    时间: 2022-10-29 20:00
谢谢!再请教一下,Angle_q是不是开环时候假定的转子Q轴角度,同步以后就是观测器算出来的真实转子Q轴角度?
作者: Angus    时间: 2022-10-29 20:57
游客 223.104.219.x 发表于 2022-10-29 20:00
谢谢!再请教一下,Angle_q是不是开环时候假定的转子Q轴角度,同步以后就是观测器算出来的真实转子Q轴角度 ...

是的。
另一角度看,Angle_q 总是是坐标旋转的角度。起转时软件控制角度,同步时用估算的角度。
作者: admin    时间: 2022-11-21 16:08
M451  可做 FOC + PFC 方案。 也可做 FOC + CAN通信 方案

七段式SVPWM 算法,一个PWM 周期有两次电流注入,所以电流频率是PWM 频率的两倍,PWM 频率若用10KHz(周期是 100us),电流频率主要是20KHz,所以噪音已比较小。

此M451 FOC 方案,PWM(ADC)中断耗时20us左右,所以另一组PWM  完全有时间做 PFC 控制。

我们推荐以下引脚配置, 同时留出CAN 通信引脚。PA2,PA3 可控制大功率 PFC 的主管和副管。


作者: Angus    时间: 2023-2-15 17:19
本帖最后由 Angus 于 2024-9-12 14:30 编辑

停转时一定关功率管吗? 停转后可以去状态0关功率管,也可去状态5 保持小电流锁定状态。这个由宏定义 MOTOR_STOP_STATUS 配置。

状态2输出0电压,若 RPM_Set >= RPM_STOP_VALUE,  上三管保持关断 , 下仨 MOS 输出使能,七段式SVPWM下管只导通50% 时间,所以不会刹车,可以给自举电容充电。
main()开头,外设初始化时,进状态2 等50ms,就是给自举电容充电 50ms(RPM_Set 初值= RPM_Stop_Value -1)。

状态2 代码见下面截图:
1> 397行,若 RPM_Set  >= RPM_Stop_Value 时,PWM->MSKEN = 0x15。就是关上MOS, 只下MOS 输出使能。 否则哪路输出使能由中断外决定。


状态5锁定后,检测转速设定值 RPM_Set 是否大于0(301行),转速设定值大于0才起转,否则保持锁定状态,代码截图如下:













作者: Angus    时间: 2023-2-16 09:27
本帖最后由 Angus 于 2023-2-21 10:16 编辑

此代码起转方式,是 I/F 起动,还是V/F 起动?

这两种起动方式可以在代码中选配,由宏定义 __DO_CURRENT_PI_WHILE_ACTIVE  配置。

若选配了起动过程中做电流PI,就是I/F 起动,起动时,在状态2给自举电容充电后,变状态5磁体先吸到某个位置(这里耗费较长时间),再变状态4控制起转过程。整个过程电流是受控制的,对保护控制器比较有利。


若未定义__DO_CURRENT_PI_WHILE_ACTIVE ,就是起动过程不做电流PI控制, 起动时,在状态2给自举电容充电后,变状态3控制起转过程,起动过程稍快,但不做电流控制,电流波动较大。所以起动电压不要太大,防止电流冲太高对功率管不利


作者: Angus    时间: 2023-2-19 12:36
本帖最后由 Angus 于 2024-9-12 14:33 编辑

PWM  频率 15KHz 以上,用五段式 SVPWM, 可降低功率管开关次数,减小功率管发热量。
若 PWM 频率较低,10KHz 以下,就用七段式 SVPWM ,可降低 PWM 频率开关噪音,因为电流通断频率是 PWM 频率的两倍。

函数 M4_SVPWM() 是按五段式计算出的、三对PWM 的不供电时间。在本例中,就是PWM 低电平时间,是两边低电平时间和。把三个指针返回值,除2后写入占空比寄存器即可。

如果要用七段式,低电平最短的那路PWM, 低电平时间 temp16 要减半,另两相低电平时间,也减去 temp16/2

返回值 Section 的低16位,是 T1+T2,  即最大导通相的高电平时间。所以 temp16 = PWM周期 - Section 就是:低电平时间最短那相的、低电平时间。
五段式变七段式,只要三个指针返回值,都再减 temp16/2 就可以了,代码如下。


返回值 Section 低16位是 T1+T2 未修正值,如果它超过周期值了,就不必减了。





作者: Angus    时间: 2023-2-21 22:23
本帖最后由 Angus 于 2024-9-12 14:36 编辑

Vd_out_f17, Vq_out_f17 是电流 PI 计算出来的,有可能它俩的模大于母线电压,再计算 SVPWM 时,就会出现 T1+T2 > PWM 周期的情况。这时会修正 T1+T2 = PWM 周期,输出电压就比 Vd_out_f17, Vq_out_f17 小了,这时若用Vd_out_f17, Vq_out_f17做位置估算,比实际输出电压值大,位置估算数值就出错了。

因此 SVPWM 若 T1+T2 > PWM 周期,就要修正 Vd_out_f17 = Vd_out_f17 * PWM 周期/(T1+T2),  Vq_out_f17 =  Vq_out_f17 * PWM 周期/(T1+T2),如此 Vq/Vd 又等于实际输出电压了。

代码如下
在做 SVPWM 时,I_beta,I_alpha  二者已赋值去掉15位小数的电压值Vq_out_f17, Vd_out_f17,  Section 的低16位是未修正的 T1+T2
把电压修正后,552,553行恢复小数位后,赋值给Vq_out_f17,Vd_out_f17


此处修正用的不是PWM 周期,而是 Pwm_Duty_Uplimit,因为这个值是计算 SVPWM 的上限,T1+T2 大于这个值,就会修正到这个值。

作者: Angus    时间: 2023-2-24 21:59
本帖最后由 Angus 于 2023-2-25 20:28 编辑

为什么 T1+T2 > Pwm_Duty_Uplimit 时,就要等比例减小T1,T2 呢, 这个上限本应该是 PWM 周期,为何可以比 PWM 周期小呢?
  
当 T1 + T2 = PWM 周期时,输出电压达到最大,电压向量就是下图中、最大的那个边长为(VDD*2/3)的六边形,这种情况,上管导通的占空比很大,下管导通时间很短。双电阻测电流方式,因不能轮换测电流相,可能会在某个时刻测不到电流,或因下管导通时间太短,测到的电流误差太大,影响角度估算。


在红蓝相输出电压最大时,红蓝相下管导通时间几乎=0。


如果 SVPWM 计算时,限制 T1+T2 最大= PWM*0.8,则输出电压向量的六边形大小,就减小到80%,限制了下管导通的时间 >= 20%.  这样在下管导通时测电流的时间就很宽裕了,当然,这样最大输出电压也低了一些。


作者: Angus    时间: 2023-3-2 22:00
本帖最后由 Angus 于 2023-3-3 16:00 编辑

观测器函数M451_FOC_Reckon()总在执行,只是在磁铁不转时,估算出的磁铁角度数值 Estimate_Q_Position 会大幅度跳动,数值是随机的。

电机转起来后,有了反电势,反正切估算出的角度Estimate_Q_Position 跳动幅度变小, 当数据跳动连续N 次小于某个值时(代码中可配置),就认定磁铁角度估值准确,就是估算已收敛,变量Position_Explicit 变非0。但这时电磁场与磁铁的位置不一定是90度,可能大于90度,也可能小于90度。



起转时,电流强托,电磁场角度逐增 Angle_q += Pull_Ommega >>16;
估算收敛后,启转函数Adjust_Pull_Ommega() 中会加快、或减慢电磁场的转速Pull_Ommega,向永磁体垂直方向靠近, 同时返回磁铁垂直方向(Q轴)与当前电磁场的角度差Estimate_Q_Position - Angle_q,做为调整电流的依据。







作者: Angus    时间: 2023-3-20 22:19
从黄色估算角度的曲线来看,角度很快就收敛了。
启动10ms 左右角度就收敛了。这个图一大格200ms,只有开头的一点点时间,角度不准确,几乎看不出来。





作者: Angus    时间: 2023-3-30 11:36
本帖最后由 Angus 于 2023-3-31 21:58 编辑

这里讲一下电流 PI 参数的取值问题

电机可以看成一个电感串一个电阻,其拉氏变换是 1/(sL+R), PI 控制的拉氏变换是 (Kp + Ki/s) , 这俩公式看不懂的,请去复习一下拉氏变换
电流的 PI 控制图如下,x是电流设定值,y是电机的实际电流。PI 控制的输出是电压V,电压加到电机(电阻+电感), 又调整了电流大小,控制的最终结果是 y=x 。因为有积分运算,所以只要 x-y >0, PI 运算的结果V 就会一直增加,所以电机电流y也一直增加,直到 y=x。


上图写成公式

公式化简

令 Ki = K*Kp, K是一个常数,公式变为



上式可变成 y 的二阶微分方程,求出 y  的解,用拉氏反变换的方法也可求出 y 的解。
当设定电流不变、即x=常数时,y 的解的形式是:
其中 x1,x2 是 S 的一元二次方程   的解。我们先不求解,讨论解的形式,比较简单。

S的一元二次方程有俩实数解时,y 的解中,e的指数是实数,y 的值指数变化(增加或衰减)趋于终值C0,没有振荡。
如果上述一元二次方程的解是复数,e的指数是复数,按欧拉公式,就是y的解是三角函数、乘e指数。y的解有三角函数,就是电流 y 有振荡。PI 控制效果、是振荡式趋于稳定值C0,这是我们不希望的。
上述S的二次方程有实根,必须满足:

上式可写成 ,第二个括号内的值 >=0,就满足整个公式>=0。

从第二个括号内式子 4RKp - 4LkKp >=0 得出 R - LK >= 0,即 K <= R/L
所以,Ki 满足下式,  电流响应就不会有振荡:

这就是 Ki 取值的理论依据,实际上 PI 控制环路还有PWM  滞后一个周期等其它微小滞后因素,Ki 的这个临界值,比 R/L*Kp 还大一点,也就是只要Kp的取值不会引起振荡,Ki 取值 = R/L*Kp 也不会振荡。


作者: Angus    时间: 2023-4-10 11:00
本帖最后由 Angus 于 2023-4-10 13:27 编辑

Kp 如何取值呢?

楼上已推导出 Ki 取值 = RKp/L,我们重新推导楼上过程,


上式,是一阶低通滤波器的公式,低通的带宽(或转折频点)是

套用拉氏反变换公式,可求出冲激响应。或者把上式变成微分方程也可求出时域解为下式:

冲激响应的积分,是阶跃响应。对上式求积分,得到输入突变时的输出公式、和函数图形如下。


低通,除了用带宽描述,还有一种描述方法是: 阶跃上升时间,一般取“输出上升到1-1/e ”的时间,做为上升时间,如上图,t=L/Kp 时上升到 1-1/e。
电机的电流 PI 控制,电流上升时间一般取15个PWM周期以上,上升太快,输出容易振荡。
我们代码中的注释,建议取值 20~100个 PWM周期, 即低通带宽是 PWM 频率的 1/20~1/100
确定了低通带宽,就确定了Kp


这就是电流 PI 控制系数的计算方法。






作者: Angus    时间: 2023-4-11 11:22
本帖最后由 Angus 于 2023-4-11 11:26 编辑

前面推导可知,电流 PI 系数可按下式确定



L,R 是电机线圈的电感、电阻, N = 20~100

作者: Angus    时间: 2023-4-16 13:00
本帖最后由 Angus 于 2024-9-15 16:15 编辑

按前面所讲,令PWM 频率是 fp, 则比例系数  Kp = 2*3.14159*fp*L/N,  N=20~100,为计算方便取值 10*3.14159=31.4159  ,变为 Kp = fp*L/5

推导 PI 系数,用的是标准单位,电压用伏特,电流用安培,电阻用欧姆,电感用亨利。 电流比例运算 V = Kp*I ,

M451 代码中,电流 PI 运算结果,是 0.1V 的数值再增17位小数的变量 Vq_out_f17,比例运算公式两边乘10* 2^17, 变为 (10*2^17)*V = (10*2^17*Kp) * I ,

电流用的是 ADC 值再增5位小数的数值 Iq_Meas_LPF_f5。假如电流采样电阻是 r, 运放倍数是A, 1安电流(5V参考电压,12bit)ADC值就是 Ar*4096/5。再增5位小数,就是再乘32。比例运算公式变成
(10*2^17)*V = (10*2^17*Kp) * I *( Ar*2^32/5)/ (Ar*2^32/5),
等号左边是Vq_out_f17,等号右边下划线部分是 Iq_Meas_LPF_f4(的误差),   公式变成
Vq_out_f17 =  (10*2^17*Kp) / (Ar*2^32/5) * Iq_Meas_LPF_f5 。   

所以比例系数  Kp_Current =(10*2^17*Kp) / (Ar*2^32/5) = 50Kp/(Ar)
再代入Kp = fp*L/5,得出比比例系数 Kp_Current = 10fp*L/(Ar) ,  这里L,r 用亨利/欧姆,或者毫亨/毫欧

  

积分系数 Ki_Current = Ki*T = Ki/fp = Kp*R/L/fp,  所以 Ki_Current = Kp_Current *R/L/fp = 10R/(Ar), R是电机绕线电阻,r是电流采样电阻。

所以, M451 代码中,电流 PI 系数用以下公式求得:

A是运放倍数。  电机 L/R 和电流阻 r 用欧姆、亨利, 或者毫欧、毫亨。



上图 406 行求出电流误差,409行是用M4内核的饱和运算指令qadd加增量 ,即 Vq_out_f17 = Vq_out_f17 + I_beta ;



作者: 匿名    时间: 2023-4-25 11:58
标题: RE: 15万转无感弦波: 风机水泵吸尘器,航模电调压缩机
请楼主讲一讲,为何电压向量要乘2/3 ?
A 相接电源 BC 接地时,假如一相电阻是R,  BC 相并联电阻是R/2,
所以 A 相分压是 VDD*2/3,BC 相分压是 VDD/3,
而 BC 相电压在 A 相方向的投影都是VDD/6, 如红色线。BC 相合成的向量是 VDD/3,

这样 ABC 相电压合成向量,应该是 A 相的 VDD*2/3 加 BC 相的 VDD/3,应 = VDD。  
但所有资料里都说是 VDD*2/3   ? 而且没有解释





作者: Angus    时间: 2023-4-29 21:00
本帖最后由 Angus 于 2023-5-3 22:00 编辑

前面乘 2/3 是等幅变换。等幅变换是电压向量的模、等于相电压幅值的变换。

以下是推导:
假如 A,B,C 三相电压依次滞后120度,相电压幅度都是U, 就是如下图形和三个公式

三相线圈,空间上的位置是:A相在0度,B相在120度,C相在 240度(或-120度),所以三相电压的“向量和”就是下式


我们对此三相电压的向量和,化简一下



以上推导结果可知,三相电压的“相电压”幅度如果是U,  接到三相电机上,产生的电压向量:是模 U*3/2 的、均速转动的向量。
我们国家的三相电是220V, 有些国家的三相电是110V, 还有些国家用的是 240V,

假如你在国外见到一个用电器,用 ADC 测到某个时刻、此电器输入的三相电压的瞬时值是 ADC_a, ADC_b, ADC_c,此用电器接的电压是多少伏呢?显然只要求出此三个ADC 值的向量的模,然后再乘 2/3 就是三相电压的“相电压”幅值
  
所以,电机 FOC 控制,在求电压(或电流)向量时,乘系数 2/3 是等幅变换,求出的是方向不变、但 "模=相电压幅值" 的向量。




作者: 匿名    时间: 2023-5-11 22:26
Angus 发表于 2023-4-29 21:00
前面乘 2/3 是等幅变换。等幅变换是电压向量的模、等于相电压幅值的变换。

以下是推导:



作者: Angus    时间: 2023-5-29 21:03
本帖最后由 Angus 于 2023-6-1 09:15 编辑

以下起转函数,函数 Adjust_Pull_Ommega()可以重载,所以可直接用这个函数名,加到文件中



若有兴趣,可对此函数优化, 起转有很多方法



作者: 匿名    时间: 2023-6-7 21:43
角度很小时,角度值=正弦值=正切值,所以下图不求反正切,直接用 Vd/Vq 代替Theta_e 是否也可以?



作者: 匿名    时间: 2023-6-8 11:17
Angus 发表于 2023-5-29 21:03
以下起转函数,函数 Adjust_Pull_Ommega()可以重载,所以可直接用这个函数名,加到文件中

这部分调整思路本省就是有问题的,估算角度-实际角度,调整方法中很多地方用到了估算角度,前提条件是估算角度是准确可靠的,既然估算角度已经可靠了,还要什么if拖动?直接速度闭环启动不就行了?
作者: Angus    时间: 2023-6-8 17:25
本帖最后由 Angus 于 2023-9-4 09:59 编辑
游客 58.49.24.x 发表于 2023-6-8 11:17
这部分调整思路本省就是有问题的,估算角度-实际角度,调整方法中很多地方用到了估算角度,前提条件是估 ...

能提出这个疑问,说明你用心思考了,先给你赞一个。
是“估计角度Estimate_Q_Position - 拖动角度Angle_q“

坐标变换函数用的 q 轴角度是 Angle_q,拖动时Angle_q 是代码控制值递增、没用估计角度,因为估计角度还不准。所以拖动时实际电流方向是Angle_q 。

拖动转起来后估计角度Estimate_Q_Position 慢慢准确了,即估算收敛了,但估计角度与 Angle_q 不一定重合,有个夹角,即:电流方向(Angle_q)与“磁铁垂直方向Estimate_Q_Position”有个夹角。



另外磁铁角度刚开始收敛时,估计位置若隐若现,角度时而准确、时而不准(角度数据跳动),电流方向若立即使用估计角度,效果并不好, 逐步接近效果反而更好。
作者: Angus    时间: 2023-6-12 10:58
本帖最后由 Angus 于 2023-9-4 10:58 编辑
游客 223.166.142.x 发表于 2023-6-7 21:43
角度很小时,角度值=正弦值=正切值,所以下图不求反正切,直接用 Vd/Vq 代替Theta_e 是否也可以?

正弦值 < 弧度值 < 正切值。 角度很小时,三者的值差不多,可以约等于。

理论上,我们需要减小实际角度与估计角度的偏差,所以计算出角度偏差做反馈量,引入的计算误差最小。
用正切值 Vd/Vq 虽然也可以,但实际角度偏差稍大,就会引入较大计算误差。现在的单片机计算能力很强,不必为了省一点点微不足道的计算量而损失精度。

思路打开,还有一种算法,就是用d轴反电势 Ed 做为后面 PLL 的输入,省掉了除法运算,但缺点是相同的实际角度偏差,反馈量受转速影响。

反正切+PLL ,角度校正量只与角度差成正比,与转速无关。
作者: 匿名    时间: 2023-6-25 16:59
我用的M453板子,220V交流供电,采样电阻0.1欧姆,放大倍数5倍,由于驱动电路原因,PWM频率只能用7K左右,家用油烟机变频风机,电机相电阻20欧姆,Ld=50mH,Lq=50mH,电机是4对极,请教一下我怎么设置参数才可以初步转起来?
作者: Angus    时间: 2023-6-25 18:05
本帖最后由 Angus 于 2023-7-1 22:03 编辑
游客 116.30.102.x 发表于 2023-6-25 16:59
我用的M453板子,220V交流供电,采样电阻0.1欧姆,放大倍数5倍,由于驱动电路原因,PWM频率只能用7K左右, ...

这个贴子里有个 “M451无感FOC_V23.03代码说明” 文件。你先根据这个文件,把PWM 输出极性,电感参数,电流ADC常数,最大工作电流,等等参数配置正确。

转速PI 参数可以先小一点(加速度会小一点,容易起转),电流PI 参数按注释方法计算出具体值。

起转电流可取最大值的1/3~1/2,起转加速度设置可以小一点。就可以试着起转了。

你还可以电话或邮件向新唐技术人员咨寻细节,或带着实物到新唐办公室调试起转。
作者: Angus    时间: 2023-7-2 23:11
本帖最后由 Angus 于 2024-9-15 16:46 编辑

为简化代码逻辑,无论电机是转是停,都会估算角度并做SVPWM 计算,只是停转时关了功率管,起转时不用估算的角度(因角度还不准确)

状态机变量Motor_Status 的不同值,标识电机停转、起转、同步,等等各个状态,控制代码的执行分支。





无论电机在转、还是停,函数M451_FOC_Rekon() 每个PWM 周期都在执行完成以下三件事:
1>,更新角度偏差Theta_e
2>,估算磁体角度Estimation_Q_Position, 并计算出角度增量做函数返回值
3>,初步判断估算是否收敛:角度偏差(PLL的输入)Theta_e 若连续多次较小,就认为角度已收敛,变量Position_Explicit 写成非0值;若角度偏差较大就 Motor_Status &= ~0x30 清零 bit4/5

起转时,何时切同步转动,除了估算角度收敛之外,一般还有其它条件,比如转速超过某个最小值,已转过一定角度等等。






作者: Angus    时间: 2023-7-26 16:08
本帖最后由 Angus 于 2023-7-26 17:33 编辑

今天让一个电机反复改变转动方向,测试快速起转是否顺畅。无霍尔 FOC 控制,能做到这么快的改变转动方向,效果不错。上视频 Reverse.zip (2.96 MB, 下载次数: 554)

作者: Angus    时间: 2023-9-15 15:31
本帖最后由 Angus 于 2023-12-28 14:38 编辑

我们测试过10万转吸尘器,测试过220V大风机,测试过不均匀转动的活塞压缩泵,测试过48V汽车空调压缩机,验证我们的观测器和起转方法的通用性,测试都没问题。






作者: Angus    时间: 2023-10-3 21:30
本帖最后由 Angus 于 2023-10-29 18:00 编辑

M451无感FOC方案特性:
1,磁链估计,比电流估计精度好。
2,dq轴估计,比静态坐标轴估计误差小,因为Ld,Lq是常量,而ab轴的电感是随角度变化的,静轴估计理论上就有误差。
3,反正切输入PLL, 比Ea*sin+Eb*cos 输入PLL好,因为前者的值只与角度偏差有关,而后者的值还受转速影响。
4,定点数运算比浮点运算快。电机最小电感仍可10uH以下。我们测试了电感9uH 的吸尘器,起转很好。
5,M4内核有除法指令,更有“抗饱和累加“指令,写代码方便,运算速度快。
6,M451工作电压范围2.5~5.5V, 宽工作电压范围,抗干扰能力强。


作者: Angus    时间: 2023-10-27 17:00
M451无感FOC方案,测试飞行器螺旋桨的视频,示波器上可看到电流波形正弦度很好

电调测试.zip (2.38 MB, 下载次数: 491)

如果不固定住,就要起飞了


作者: a20084666    时间: 2023-10-27 17:39
Angus 发表于 2023-10-27 17:00
M451无感FOC方案,测试飞行器螺旋桨的视频,示波器上可看到电流波形正弦度很好

的确不错
作者: Angus    时间: 2023-11-26 17:17
本帖最后由 Angus 于 2024-9-15 16:21 编辑

这里讲一下短路保护代码。 逻辑关系有点绕,但工作可靠。
短路信号接到 PWM 的 Brake 功能引脚,短路时,PWM 输出立即关闭功率管、然后产生 Brake 中断。
进 Brake 中断后 811 行写标志,表明执行过Brake中断,用于中断外检查。
812 行写标志,表示关了功率管。如果干扰较强,可采用 BrakeCount 计数的方式,两次或三次 Brake 信号确定是短路了,就保持关功率管关闭。 如果硬件做的好(比如用IPM)短路信号没有干扰,一次 Brake 信号就有效。

清除 Brake 中断标志 PWM0->INTSTS1 后 PWM 的输出就会恢复,不清除 Brake 中断标志退出中断后又会反复进 Brake 中断,所以 816行关了 Brake 中断再返回 ,这样即可保持功率管关闭,又不会反复进 Brake 中断了。  




Brake 中断里不能改写状态机 Motor_Status = 0, 因为Brake 中断优先级高,后续可能返回 ADC 中断又被改写,可能打乱 ADC 里的状态机。在中断外、主循环里有“是否发生 Brake ”的检查和后续处理,如下 297 行在这里,改写Mortor_Status =0 才是可靠的。296行把 Stop_Runing 相应位写1,后面检查此标志,RPM_Set 会一直赋值为停转值,不再起转。



以后,只要 Stop_Runing 不清0,406行都会把转速设定值 RPM_Set 写成 <=0 的停转值,Motor_Status 会保持在0、电机自由停转,不会再重新启转。



执行到 343 行时,检查短路是否已解除。 若短路保护已解除,即 Brake_No_Resume =0 了,这里清除 Brake 中断标志PWM0->INTSTS1 、恢复 PWM 输出,重新使能 Brake 中断。Stop_Runing 的短路标志也清除,但此时 Motor_Status=0,因在ADC 中断里有 PWM0->MSKEN = 0 , PWM 引脚输出仍保持着关闭功率管。



功率管如果用的是 IPM , 短路时 Fo 输出几十 us 低脉冲,然后输出高。如果是15V 太低,Fo 会持续输出低,二者都会产生 Brake,  所以, 如果后续检测到是 15V 太低,不是短路,也解除短路保护。

如果没有其它错误,Stop_Runing=0, 后续转速设定值 RPM_Set 就可以正常赋值了。一切从新开始,由 RPM_Set 的值决定是否启转。








作者: Angus    时间: 2023-12-28 11:39
本帖最后由 Angus 于 2024-7-15 18:06 编辑

起转时,即可以线性加速,也可以指数加速。
线性加速的好处是,起转时,如果想让转速慢慢稳定增加,就采用线性加速。

起转开始时,位置不收敛,转速较低,执行63~64行代码,转速逐步增加。
转速低于上限时,64行是线性加速。63行,转速增加一个百分比,这是指数加速度。
然后83行Pull_Ommega_f16 去掉16位小数,加到“位置”角度值 Angle_q 上。  



调用函数时,如果实参一用0值,63行转速增加百分比=0,就取消了指数加速,转速仅线性增加。




作者: a20084666    时间: 2024-1-2 14:07
上桥180欧姆的电阻,感觉很大
作者: Angus    时间: 2024-1-2 20:34
功率管栅极电阻,要根据功率管特性调整。开关慢了发热多,开关快了可能会振荡,发热也会多。
作者: Angus    时间: 2024-1-17 21:06
本帖最后由 Angus 于 2024-9-12 16:17 编辑

今天调试一个新板子,总结一下调试步骤:修改好电机Lq, Ld,绕线电阻RESISTER_COIL,以采样电阻及运放倍数CURRENT_Adc1000以后,核对以下事项

1,核对PWM,  PWM024 驱动上MOS,  PWM135 驱动下MOS。如果不是这样,代码改动稍大。
2,核对PWM 的输出极性,PWM 输出高时功率管导通,如果不是,在函数PWM_Init()中124~125行注释或放开反相函数。

3,核对电流运放的极性,电流流入电机时,运放输出电压增高。电流 ADC 的值为正。若正负反了,在ADC 中断里把Current_PWM01/PWM23/PWM45 数据取反。

4,核对电流 ADC 输入引脚与输出 PWM01/23/45 对应关系。

以上若没错,可以烧录代码,通电了。若转速旋钮=0,上电后在状态0,功率管关闭。这时可以在 ADC 中断代码中增加一个状态7(下面详述两处代码改动)。然后在仿真状态,依次写变量的值 Motor_Status=7,   Angle_q=0,PWM->MSKEN=0(PWM输出),  Id_set_f12 = CURRENT_Adc1000<<2 (电流值=1A), 这个时候,Current_PWM01的值刚好是1A电流对应的ADC 值。

调试电路,代码如下稍做修改。
ADC 中断里,349 行这里是增加的状态7,什么都不用做,这个状态用于仿真状态直接变量的值


main.c 中主循环这里,333行,增加if(Motor_Status != 7)排除状态7,即状态7也是什么都不做。


CURRENT_Adc1000 = 0xB333, 此值相当于0.25A电流值,设定电流1A, 就是把 Iq_Set_f12写成其4倍的值 = 0x0002CCCC
如下图,10毫欧电阻放大5.6倍相当于56毫欧。
电流1A时,5V 参考源,12位ADC 值是: (1A*56毫欧/5000毫伏)*4096 = 45.875,  仿真看到 Current_PWM01 = 45,
如果Current_PWM01的值若比45小,可能是A相电流有振荡或ADC转换时间窗太短。不过,在0度时,代码中是用Current_PWM23/PWM45计算Ia,Ib的, 所以,只要Current_PWM23/PWM45的电流和=45电流控制就是对的,不影响控制。


输出电压 Vq_out_f17 =1441344,右移17位得0.1V的数值是 : 1441344/131072 = 11,  即输出电压Vq是1.1V,电机电阻是1欧,这个电压值也是对的。







作者: Angus    时间: 2024-2-8 18:00
本帖最后由 Angus 于 2024-7-16 09:04 编辑

有这个宏定义是 I/F 起动,启转阶段从功率管开始工作,电流就在控制范围内。即使换一个型号的电机、电感电阻有较大变化,也不易烧功率管,这是优点。建议初学者先用这个方法试着让电机起转。



若把此句注释掉,就是 V/F 起转,好处是起转快。因起转阶段不做电流 PI 控制、电流波动大,所以需小心确定起转电压。若换个型号的电机、电感电阻参数差异较大,需调整起转电压,否则可能过流。

作者: 匿名    时间: 2024-2-23 14:39
Angus 发表于 2022-10-27 21:48
电压的基准值是 0.1V。最大值是 16383,若超过此值, 乘4后大于等于65536做坐标旋转会溢出,即最大工作电压 ...

楼主,每次都要采样母线电压的值吗?不太明白,母线电压不是固定不变的吗?请楼主解惑。另外,原理图对不上啊,能否分享一张实际的原理图,采样的是那个点,采样的是相线电压还是母线电压,谢谢!
作者: Angus    时间: 2024-2-23 18:44
游客 223.112.186.x 发表于 2024-2-23 14:39
楼主,每次都要采样母线电压的值吗?不太明白,母线电压不是固定不变的吗?请楼主解惑。另外,原理图对不 ...

如果是交流220V 整流得到的直流,有人为节省成本母线电容用的小,母线电压波动大,这时最好每次PWM 都测一次电压比较好。

此代码是三电阻或双电阻测电流,在PWM 计数起点测电流,即下MOS 导通中间。

我测试的板子,稍做了改动,只要测到母线电压和三相电流,就能转起来。ADC 引脚用哪个、就配置哪个就行。
作者: 匿名    时间: 2024-2-28 08:41
Angus 发表于 2024-2-23 18:44
如果是交流220V 整流得到的直流,有人为节省成本母线电容用的小,母线电压波动大,这时最好每次PWM 都测 ...

谢谢楼主。
作者: 匿名    时间: 2024-3-6 15:41
关于PARK变换,求出id,iq,我下载的代码如下:(无法发送图片,只能复制)
////===求Idq,前俩实参最大正负65535(可同时最大),否则计算溢出 ========
// *_I_alpha,  输入 I_alpha 返回 Id
// *_I_beta,   输入 I_beta 返回 Iq           
//  _q_Angle   q 轴角度,[0 ~ 65536)表示[0~360)度
void Static_to_Dynamic(int32_t *_I_alpha, int32_t *_I_beta, int32_t _q_Angle)
{
  int32_t  C11,  C21 ;
  int32_t  Ia = *_I_alpha,  Ib = *_I_beta ;
  
  C11 =  _q_Angle ;
  C21 = Get_cos(&C11) ;
                                                              // 65535*0x8000+16384= 0x7FFFC000
  *_I_alpha = ((Ia*C11+16384)>>15)+((-Ib*C21+16384)>>15);     // 65536 * 0x8000   = 0x80000000 溢出
  *_I_beta  = ((Ia*C21+16384)>>15)+ ((Ib*C11+16384)>>15);     //-65536 *(-0x8000) = 0x80000000 溢出
}                                                             //-65535 *(-0x8000) = 0x7FFF8000

上面的的两个等式*_I_alpha和 *_I_beta  =,和公式不一致,楼主能给讲讲吗?谢谢@
作者: Angus    时间: 2024-3-7 08:33
本帖最后由 Angus 于 2024-4-1 10:11 编辑
游客 223.112.186.x 发表于 2024-3-6 15:41
关于PARK变换,求出id,iq,我下载的代码如下:(无法发送图片,只能复制)
////===求Idq,前俩实参最大正负65 ...

正余弦值 C11,C12,C21,C22有15位小数,所以Ia,Ib乘c11~C22后右移15位去掉小数, 加16384是四舍五入。

若不用浮点运算,整数除法,得到的只有整数的商和余数,比如 20~24 除10,=2.0~2.4, 商是整数部分2。25~29 除10,=2.5~2.9,商也是整数部分2,如何让整数部分是 3 呢?

整数运算没法加0.5,那就在被除数上,加除数的一半(等于加了0.5)。25~29, 加5后再除10 =3.0~3.4,整数部分刚好是3。而20~24 加5后除10 = 2.5~2.9,整数部分仍是 2。


也就是说,整数除法的四舍五入,是在除之前,先在被除数上加除数的一半,再做除法,结果就四舍五入了。

所以,右移15是除32768,四舍五入就在被除数上先加 16384。

作者: Angus    时间: 2024-3-24 11:16
本帖最后由 Angus 于 2024-9-15 16:28 编辑

在做位置估算时,要用到一个低通滤波器。低通带宽若太低,转速响应慢;若太高,起转时容易受干扰、同步慢。所以,可以启转成功后, 把带宽加倍,以加快转速的响应。

低通滤波器的带宽配置函数 Set_PWM_Frequency_LPF(72437760ul/gPWM_Period, 200);   参数一是数据采样频率, 即PWM 频率;参数二是低通滤波器的带宽“角频率”值 Ommega,  实参若用200,转折频点=200/3.14159/2 = 32Hz

此代码中,低通带宽在 main() 中配置后,未再配置。对于风机来说这样做没什么影响。


此低通带宽值在 ADC 中断里计算时用到,所以,可以在 ADC 中断里调用此函数、重新配置低通带宽。



作者: 匿名    时间: 2024-3-25 11:04
Angus 发表于 2024-3-24 11:16
在做位置估算时,要用到一个低通滤波器。低通带宽若太低,转速响应慢;若太高,起转时容易受干扰、同步慢。 ...

这里的低通滤波器,是为了得到一个比较平滑的反电动势是吗?能否详细讲讲。这个算法在启动和低速时和速度正常时的区别,以及如何切换的,谢谢!
作者: Angus    时间: 2024-3-26 09:07
游客 223.112.186.x 发表于 2024-3-25 11:04
这里的低通滤波器,是为了得到一个比较平滑的反电动势是吗?能否详细讲讲。这个算法在启动和低速时和速度 ...

我们是dq 轴估算,直接计算出 q 轴的电势,这个反电势直接与转速成正比。

刚启转时,电流容易受干扰 ADC 数据更容易跳动,计算出的反电势也会数据跳动,就是含有高频分量,由此计算出的转速值,也会有数据跳动。低通滤波,就是滤除数据跳动分量。实际机械转速几乎不跳动,就是频率较低,带宽较窄。

启转成功后,数据比较稳定,可以适当增大一点点带宽,加快转速响应,特别是转速会快速变化的应用。
作者: Angus    时间: 2024-4-1 12:40
本帖最后由 Angus 于 2024-9-15 16:30 编辑

电机公式是 V - Ri = Ldi/dt + E ;  位置估算输入的电压,一般先把电机绕线电阻的压降去掉,即先计算等式左边的 V-Ri
我们的代码是用电压的 25mV 数值计算的,可以保证电压不足10V的低压电机的计算精度。最大电压可到 1638.3V,380V 的电机也无需修改电压数据精度。

先计算 V- Ri, 187/188行是Vd/Vq电压的 25mV 数值。Ri 计算结果是 伏,就要乘 40 得 25mV 数值
R = 毫欧/1000 = RESISTER_COIL / 1000
i = 电流ADC值/1安电流的ADC 值
电流 Iq_Measure_f3,是电流ADC 值乘8的数值(乘8是为了后面位置估算提高精度),所以电流ADC值 = Iq_measure_f3/8
CURRENT_Adc1000 是1安电流的ADC值、再乘1000的数据,所以1安电流 ADC 值 =  CURRENT_Adc1000 / 1000
所以电流 i = (Iq_Measure_f3/8) / (CURRENT_Adc1000/1000)



40*R*i  = 40 * (RESISTER_COIL/1000)*【(Iq_Measure_f3/8) / (CURRENT_Adc1000/1000)】
上式简化后 40*Ri = 5*RESISTER_COIL * Iq_Measure_f3 / CURRENT_Adc1000
Iq_Measure_f3 有 15 位,如果电阻RESISTER_COIL 有17位,前面乘积就 32位了,就不能再乘5了,所以把乘5移到分母除5。

第208行代码本应除5,做四舍五入要加 2.5, 加不了小数,就变成加5除10。

作者: Angus    时间: 2024-4-17 17:12
本帖最后由 Angus 于 2024-4-17 22:11 编辑

新唐 M451 无感 FOC 是如何很快起转成功的?

无感 FOC 的起转,是先托动,就是电磁场吸引着转子永磁体转动。
刚开始,转子位置未知,用较大电流吸着磁铁转,所以磁铁跟得紧,电流方向与磁铁夹角小于90度,如下图。





转速稍快后,磁铁位置准确了。由于电流大转矩大,转速又慢,所以电流方向与转子夹角仍小于90度。若想让二者夹角到90度,有两个方法:
1>,加快电流转速。让电流方向,尽快转到 Q 轴位置——90度。  如果电流不减小,可能要转很多圈,电流方向才能赶上90度位置,切同步慢。
2>,减小电流降低转矩,永磁体转不动就会落后,直到落后电流方向 90度,就变同步转。 如果电流减太快、转矩降太快,重载时,还没变同步,就转不动而停转了。

所以,以上两个办法,同时使用,才能尽快变到同步转动。

这里再详细说一下电流加速度。
为了加快电流转速,我们采用了指数加速的方式。如下图

刚开始时,转速要慢,要让电流吸住磁铁转。转到磁铁位置准确了,就要尽快转到90度,这时指数加速,电流方向可很快转到90度

转速调整函数, Adjust_Pull_Ommega(Speed_Inc,  PULL_Ommega_Inc_f16 ,  PULL_Ommega_Max_f16);   
函数内这样实现
Pull_Ommega_f16 += Pull_Ommega_f16 * Speed_Inc >>14 ;      // 指数加速
Pull_Ommega_f16 += PULL_Ommega_Inc_f16 ;                        // 线性加速


拖动刚开始,如果只想线性加速,可以让实参一 = 0,磁铁位置准确了,再用非0实参。



作者: Angus    时间: 2024-4-19 17:36
本帖最后由 Angus 于 2024-7-16 09:28 编辑

状态 4 起转流程图



锁定电流 CURRENT_MotorLock_f12 的取值:大小让重载时能转得动。
锁定时间 TIME_MotorLock 的取值: 反转最大角度时,能转到位。比如想逆时针转,电流在 12点锁定,此时磁铁若在8点会是最大反转角度,锁定时长要让磁铁转到12点差不多。先用电流半值驱动,是让轻载时减缓转速、减轻在 12 点左右的来回抖动。

线性加速度 PULL_Ommega_Inc_f16 的取值,重载起动时(起转较慢), 拖动最少的圈数能起转成功,一般两三圈, 或四五圈就能同步。
轻载时磁铁跟得紧,线性加速度若取值小,要到转速较高时、要转很多圈电流方向才能追上Q轴,就用指数加速度加快电流增速。逐步增加指数加速度值,让轻载能较快同步。

拖动转速上限 PULL_Ommega_Max_f16 :比最小能同步的转速高一点。比如在500 rpm 以下无法同步转,则拖动转速上限可取值700rpm 以上。
拖动转速下限 PULL_Ommega_Min_f16 : 一般比最小同步转速小一点。比如500rpm以下无法同步转动,则拖动转速下限可取值 300rpm以下。高于此转速才判断是否同步。





作者: Angus    时间: 2024-4-24 13:25
本帖最后由 Angus 于 2024-4-28 10:00 编辑

状态 4 起转波形


从上图可见,收敛速度很快,电流方向追赶估算角度的速度有点慢。若要加快起转,就要缩短这段时间。

作者: Angus    时间: 2024-4-26 23:03
本帖最后由 Angus 于 2024-4-27 11:00 编辑

24年4月26日以后更新的代码,完善了状态 3 起转。 下图可见,切同步较快。

压缩泵起转波形,50ms 内切同步,电流 PI 值可以稍大一点,以加快响应。


风机起转波形,0.2 秒切同步


作者: Angus    时间: 2024-5-30 11:33
高压电机控制的电源部分



作者: Angus    时间: 2024-5-30 11:35

高压电机控制的 AC/DC 部分。




作者: Angus    时间: 2024-5-30 12:31
高压电机控制的功率驱动部分。



R114 的阻值按保护电流选取,取值 75欧时,保护电流 10A

作者: Angus    时间: 2024-5-30 12:32
本帖最后由 Angus 于 2024-5-30 13:53 编辑

高压电机控制的 CPU 部分。



作者: Angus    时间: 2024-5-30 13:32

高压无感 FOC 代码执行后,用 PinView 查看引脚配置



作者: Angus    时间: 2024-6-2 17:07
本帖最后由 Angus 于 2024-6-3 18:06 编辑

用新唐 M451 做的一个 24V 的空气泵,无感 FOC 控制。

反复启动的视频

24V泵反复启动的视频.zip (5.72 MB, 下载次数: 211)

示波器一大格是50ms,  可以看出,起动时间每次都不到 0.05秒。

作者: Angus    时间: 2024-7-1 11:00
本帖最后由 Angus 于 2024-7-15 13:35 编辑

积分饱和

假如输出电压最高时,电机达到最快的 5Krpm,电流稳定在3A。如果设定转速此时是 6Krpm, 转速误差仍有1K, 转速 PI 运算中的积分运算,仍会一次次增加电流设定值,一直加到控制器电流上限,假如是 20A 。  

这时如果转速设定值突然变成 4Krpm,转速 PI 结果——设定电流,从20A慢慢往下降,在降到 3A 前,输出电压不会降,所以转速不会降、保持5Krpm。只有电流降到 3A 再降时,输出电压才开始降,转速也才开始从 5k 往下降。 转速控制会有一个长时间的滞后才反应过来。这就是积分饱和、造成的不良后果。
一个性能优良的电机控制代码,一定有积分抗饱和运算




作者: Angus    时间: 2024-7-15 16:18
本帖最后由 Angus 于 2024-9-12 16:23 编辑

积分抗饱和的方法

网上查一下,有很多种抗积分饱和的方法,比如,积分分离法,输出限幅法,等等。

我们24年7月以后的代码,积分抗饱和方法是:每次做转速PI 前,检查若转速误差为负(表明指令要降速)并且输出饱和了,就让电流设定值=电流测量值,这样接下来的转速PI 计算结果,一定是降输出电压,也就是退出饱和,要降速了。


作者: Angus    时间: 2024-7-18 09:09
本帖最后由 Angus 于 2024-8-2 09:06 编辑





采用状态 3 起转,起转前不需要锁定



作者: Angus    时间: 2024-7-20 11:11
本帖最后由 Angus 于 2024-9-15 16:05 编辑

新唐M451 无感FOC 代码,做MTPA控制。

先介绍一下理论。文字中的符号, 要显示出来,必须单独上传图片,为了省事,我只好先写成 word 文件,再截成一个大图片上传了。

电流分量代入转矩公式,得


MTPA 控制就是给定电流Is,求角度等于多少时,转矩最大。求导=0得



解这个一元二次方程,得

不同Is对应的超前角可做一个折线。假如最大工作电流是32A,做8个点,4A一个点。算出N = 8*Is/32=Is/4 (取整),则Is对应的超前角在点[ N], [N+1 ]之间,按下式做一个线性计算就可得到角度



M451的无感FOC 代码,起转时Id=0,起转成功能后,第277行代码,切同步前把超前角 Angle_Fai 写成 0,如果以后不再改这个超前角,就是 Id=0 控制。



若要做 MTPA 控制,就在 SysTick 中断里、转速 PI 运算得出 Is 后,再查表求出超前角 Angle_Fai就可以了,求 Iq,Id的代码已写好。




M451做MTPA 控制.pdf

332.75 KB, 下载次数: 278


作者: Angus    时间: 2024-8-2 09:00
Angus 发表于 2023-10-3 21:30
M451无感FOC方案特性:
1,磁链估计,比电流估计精度好。
2,dq轴估计,比静态坐标轴估计误差小,因为Ld,Lq ...

观测器理论不错,起转效果也不错。PWM 中断只用了 20us 多点,MCU 还有很多算力可以利用,接下来是加上高频注入法呢,还是加上 PFC 功能呢 ?

高频注入法中的旋转电压法,可做到 0 速时测到磁铁位置,让电机像有感一样转动,听起来就不错。

冰箱,洗衣机,大风扇等 220V 的应用都需要 PFC 功能,并不在意起转时,反转一个小角度。一个芯片做成电机控制+PFC 是个很受欢迎的方案。

作者: Angus    时间: 2024-8-13 11:39
MTPA 控制就是用最小的电流,获得最大转矩 。为什么要获得最大转矩,基础理论是什么 ?

牛顿第二定律  

力矩 = 半径 叉乘 力,
把 "质量与半径平方的积" 定义为转动惯量 J 后,转矩与角速率的关系,和牛顿第二定律一样,称为转动的牛顿第二定律

上式可见,相同的转动惯量,转矩大,角速率的斜率大,即提速快。如果没有摩擦力,会一直加速。
实际的负载——被外力驱动的物体,转速与转矩的公式,是下式:B 是一个常量系数

这是个一阶微分方程,解这个微分方程,可得转速公式与转矩的关系式为:

此函数的形状是这样的。最终转速是 M/B


对于同一个负载,显然,若外加的转矩大,不仅最终的转速高,提速也快。

如果不需要达到电机的最高转速,转矩大的电机,负载达到设定转速的时间短。




作者: Angus    时间: 2024-8-13 15:00
本帖最后由 Angus 于 2024-8-13 15:17 编辑

MTPA 控制为何比Id=0控制,消耗的电流会小

假定转矩 T 是个常数,电流 iq,id 就是反比关系,Te 公式的意义,见前面回帖。



Iq 与 Id 的函数图像,可以看成是  y= - 1/x 向右平移。如下图

控制器的输出功率,与电流的模有关,即 Is

以 Is 为半径的圆上,控制器的输出功率是相等的。

在电机基速以下,即未达到最快转速时,下图蓝色 Te 是等转矩线,可以理解为负载等转速线(确切来说,应是输出转矩曲线才是负载等速线)。其原理见楼上回帖的讲解。

如果采用 MTPA 控制,达到这个转速,所需电流是蓝色箭头 Is2 。

如果采用 Id=0 控制,达到这个转速,需要的电流是红色箭头 Is1,已超出以 Is2 为半径的圆圈 。

此图很明显得看出,相同转速, MTPA 控制所需的电流 Is2比 Id=0控制所需的电流 Is1 小。




作者: Angus    时间: 2024-8-13 16:19
本帖最后由 Angus 于 2024-8-13 16:26 编辑

查表法 MTPA 控制,要先按下式计算出不同电流 Is 下的超前角,做成一个表格。



电机的电阻和电感,都好测量,但磁链常数怎么测量呢?



电机参数里,会给出反电势常数 Ke,  可以按下式求出磁链常数,这里频率 f 是每秒的转速,不是每分钟的转速。

如果不知道电机的参数, 测量磁链常数的最好办法是,用另一个电机拖动,用出示波器测出反势电压峰值,再按上式算出磁链常数。



如果找不到合适的方法用另一个电机拖动,可以让电机空载转起来,采用 Id=0 的控制方式。用下式求出磁链常数。

电机均速转时,Iq 是个常数,求导=0,第一个公式,等号右边前两项=0,  公式就成了下式:

上式等号右边是反电势。转速高时反电势高、计算误差小。
这样就可求出电机的磁链常数了。

在新唐 M451 无感 FOC 的代码中,反电势数值是变量 EMF_Multi_Unit_Magnify , 此变量每个PWM 周期估算位置时更新一次,对此变量低通滤波后,就得到一个稳定的反电势数值。





作者: Angus    时间: 2024-9-16 09:00
积分抗饱和运算

如果电机转速已到最大,而设定转速仍比实际转速大,转速 PI 的积分计算仍一直增加电流设定值,最终电流设定值加到上限,可能比电流实际值大很多倍。如下图电流设定值一直加到了高位 =0x0019,十进制的25,比电流实际值 Iq_Measure 的高位= 2,大了12倍多。

这时如果设定转速 RPM_Set 调到 4767 以下,电流设定值要很久才能降到电流实际值以下,而这期间转速不会下降,这就是积分饱和引起的调节滞后,不好的使用体验。




假如本次转速误差 Err_Spd =K,K>0,  
下次 PI 运算时前 Err_Spd_Last = Err_Spd = K ; 到时候若转速设定值与转速实际值一样,即 Err_Spd = 0 ;  则转速 PI 运算就是
temp32 = (Err_Spd - Err_Spd_Last)*Kp_Speed +Err_Spd*Ki_Speed = -K * Kp_Speed ;   
如果下次刚好能让“电流设定值 = 电流实际值”, 那么就不会积分饱和。

即本次转速 PI 计算的电流值若等于下式,下次转速 PI 运算就可以把增量减去,不会积分饱和


本次电流设定值 =  K * Kp_Speed + 电流实际值 = Err_Spd * Kp_Speed + 电流实际值 ;  // 这个是本次电流设定值的上限


K 值取多少呢? 因转速控制精度1%以下,可取转速最大值的 1/64。所以有以下积分抗饱和运算代码:



这段代码的执行效果如下图,电流设定值只增加到实际值的 2.7 倍,这是下次能一次把电流误差回调到 0 的值。





作者: Angus    时间: 2024-9-17 11:00
本帖最后由 Angus 于 2024-10-2 21:11 编辑

电机启动流程

更新转速设定值 RPM_Set ,不是一个很紧急的事件,在 main() 主循环中,按旋钮 ADC 值确定转速设定值 RPM_Set 是多少。

在main() 主循环代码中,电机可能在同步转,也可能未在同步转。分别做如下处理:



一,如果电机在同步转(Motor_Status 的 bit4 非0),下图318行,做以下事情:
如果 RPM_Set  <= 0,  说明电机已在停转降速中,这时需判断一下,若转速已降到最小值以下,就去状态 1 刹车停转。
如果 RPM_Set >0,  这里不需要做什么。电流大小由SysTick 中断里、转速 PI 计算结果决定;电压角度和 PWM 输出占空比,由 ADC 中断里计算、输出。

二,如果电机未在同步转, 下图327 行,要么不需要起动(RPM_Set <= 0),要么需要启动(RPM_Set >0)。



1>,如果不需要起动(RPM_Set <= 0),又已在起动流程(状态3,4,5,6),则直接刹车停转(335行, 去状态1)、或关功率管(去状态0)就行了。
       如果未在启动流程,未转、也未在启转,就判断是否取消故障状态,转向开关是否变了,等等。

2>,如果需要起动、又未在启动流程,执行到 362 行,先调用函数 Test_Period() 判断是否已顺风吹转,若是则跳转到状态6,顺风起转。若未顺风转,跳转到状态 2 先给自举电容充电,充电结束后,在状态 2,按宏定义决定跳转到状态 3 开始 V/F 起转、还是跳转到状态 5 ( 再跳转到状态4)  开始 I/F 起动。

     若需要启动,又已在启动流程,这里就不需要做什么了,ADC 中断里、启动代码会变换状态。






作者: Angus    时间: 2024-9-23 11:33
本帖最后由 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、立即停止启动,不必再等超时了。

作者: Angus    时间: 前天 10:26
今天是2024年11月20日,昨晚更新了一版代码。 增加或改变的功能如下

1, 输出电压的限幅,由原来的对 Vq,Vd 分别限幅到 0.577VDD,  改为对输出电压的模限幅 0.577VDD。后者可保证输出电压不超内切圆,输出电压波形好,但需要做开方运算。

2,增加了提速控制,可以调整加速度、或减速度。

3,在转速 PI 环外面,增加了功率闭环控制,功率闭环可精准地控制功率不超上限。





欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/) Powered by Discuz! X3.2