牛卧堂MCU技术交流

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

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

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

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

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


顺风启转,直接同步


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


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


无感 FOC 代码+原理图 M451_FOC_V23.zip (647.39 KB, 下载次数: 1671) 中文注释非常详细,量产后可开放 M4_SVPWM.lib
电机参数不同或电路不同时,代码修改说明 M451无感FOC 代码说明.pdf (1.88 MB, 下载次数: 1378)

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

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


技术支持电话
新唐上海公司   021 - 62365999

M451_FOC基本原理.pdf

1.73 MB, 下载次数: 2517


作者: 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 于 2022-11-11 10:21 编辑

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

模拟 PID 运算公式 :

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


采用增量式算法:


下面是转速 PI 运算的代码
代码600 行:增量 = Kp*[本次误差 - 上次误差] + Ki * 本次误差
代码 601 行,temp32 = U(n-1) + 增量。
603 ~ 605行,计算结果 temp32 做限幅后,再赋值给电流设定值变量 Iq_set_f12

  

这里不能对 Iq_set_f12 先赋值,再对Iq_set_f12 做限幅检查。因为ADC 中断的优先级更高,计算时若产生 ADC 中断,Iq_set_f12 的中间结果在 ADC 中断里做电流 PI 运算,数值就不对了。  



PI 系数 Kp_Speed, Ki_Speed 是有12小数的,所以 601 行应右移 12 ,未右移,就是计算结果保留了 12 位小数。做电流PI 运算时会做小数位的对齐。








作者: Angus    时间: 2022-1-23 21:36
本帖最后由 Angus 于 2023-6-8 20:58 编辑

这里讲一下 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后才与控制量对应,  这样公式就变成了

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


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










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

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


SVPWM 能输出的无失真相电压,最大值是 0.577倍的母线电压,再大, 就是削顶的正弦电压了。 227行,选择一个相电压上限值。增加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-3-12 15:28 编辑

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

转速的设置有个上限RPM_Set_Max、下限RPM_Set_Min, 还有个停转值 RPM_Stop_Value,停转值一般取负值,因为负值比0值更能让电流PI运算的结果——电流设定值——下降更快,电机停转也就更快。

状态1输出0电压,六个管子都输出PWM,七段式上下管交替导通50%,五段式下三管常通,都会刹车。
状态2输出0电压,但只下三管输出PWM, 上三管保持关断,七段式SVPWM下管只导通50% 时间,所以不会刹车,又可以给自举电容充电。main()开头,外设初始化时,进状态2 等50ms,就是给自举电容充电 50ms(RPM_Set 初值= RPM_Stop_Value -1)。

起转前,先进入状态2,给自举电容充电,充电时间到后,检测转速设定值RPM_Set,代码见下面截图:
1> 若转速设定值RPM_Set 比停转值RPM_Stop_Value 还小,就是给自举电容充电后功率管保持关断,去状态0 (201行)。
2> 若转速设定值RPM_Set 大于停转值RPM_Stop_Value,但小于0(204行),  执行完状态2 就是保持停转状态。由MOTOR_STOP_STATUS 配置是停在状态0、还是跳转去状态5保持小电流锁定。




状态5锁定后,检测转速设定值 RPM_Set 是否大于0(328行),转速设定值大于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 于 2023-2-21 20:30 编辑

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 于 2023-2-22 08:52 编辑

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
432, 433行,把电压修正后,再恢复小数位,赋值给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 于 2023-4-16 19:31 编辑

按前面所讲,令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 ,也就是做比例运算时,Kp 系数要乘 10*2^17 , 数据才正确。



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

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

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

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

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



上图 363 行求出电流误差,364行是用M4内核的饱和运算指令qadd加增量 ,即 Vq_out_f17 = Vq_out_f17 + Kp_current *[e(n) - e(n-1)] + Ki_current * e(n) ;


作者: 匿名    时间: 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 于 2023-8-15 08:50 编辑

为简化代码逻辑,无论电机是转是停,都会估算角度并做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, 下载次数: 299)

作者: 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, 下载次数: 223)

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


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

的确不错
作者: Angus    时间: 2023-11-26 17:17
本帖最后由 Angus 于 2023-12-28 11:36 编辑

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

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




Brake 中断里不能改写状态机 Motor_Status = 0, 因为Brake 中断优先级高,后续可能返回 ADC 中断又被改写,或打乱 ADC 里的状态机。在中断外、主循环里有“是否发生 Brake ”的检查和后续处理,如下 254 行在这里,改写Mortor_Status =0 才是可靠的。255行把 Stop_Runing 相应位写1,此后,271行转速设定值就会被写成停转值——小于0的负值。



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

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



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






作者: Angus    时间: 2023-12-28 11:39
本帖最后由 Angus 于 2024-1-2 13:01 编辑

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

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



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




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

最后的代码更新了什么?

代码中转速的计算方法是: 转过扇区边界时,数组Section_data[] 记录转过的精确角度和时间(PWM计数值);  记录 NUM_SECTION_AVERAGE +1 个扇区边界后,用 NUM_SECTION_AVERAGE 个扇区的角度、除时间,得出一秒转过的角度,再用一分钟转过的角度除360度得一分钟转过的圈数,就是 RPM 转速值了。
顺风起转时,要等转过 NUM_SECTION_AVERAGE +1 个扇区边界,才有 NUM_SECTION_AVERAGE 个扇区的角度和时间。所以在下图359行,Do_Spd_PI(累加到正开始做转速PI)赋值必须至少是 -NUM_SECTION_AVERAGE -1,否则开始做转速 PI 时转速数据不对,电流会突变、电流波形不连续。



另外把转速 PI 的运算频率,从10ms 一次,改为1ms 一次,加快了响应。

作者: Angus    时间: 2024-1-17 21:06
本帖最后由 Angus 于 2024-2-4 20:00 编辑

今天调试一个新板子,总结一下调试步骤:修改好电机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 中断里,364行这里是增加的状态7,什么都不用做,这个状态用于仿真状态直接变量的值


main.c 中主循环这里,307行,增加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,
在0度时,是用Current_PWM23/PWM45计算Ia,Ib的, 所以,只要Current_PWM23/PWM45的电流和=45电流控制就是对的,Current_PWM01的值若比45小是ADC转换的时间窗太短造成的。


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







作者: Angus    时间: 2024-2-8 18:00

有这个宏定义是 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-3-24 21:26 编辑

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

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

先计算 V- Ri, 196/197行是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。

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

作者: Angus    时间: 2024-4-1 15:01
本帖最后由 Angus 于 2024-4-1 15:18 编辑

如果做弱磁控制,要在 194行,增加电流求模的计算


195行,求Iq*Iq + Id*Id ,乘后除4,是防止与后面乘积相加后数据溢出。
196行,如果数值太小,为提高开方精度,先左移12、开方后再右移6。右移了5位是补偿196行开方前的右移2。


弱磁控制的转速 PI 运算结果,是电流的模 Is_set_f12
如下 708行就要变成 :
Iq_set_f12 = temp32 * cos() ;   
Id_set_f12 = temp32 * sin() ;    // 这个偏角=0时, 就是Id=0控制。偏角为负时,Id设定值负值,就是弱磁控制。
可做个“电流Is——偏角”表格,按电流的模Is 查表得偏角,再求Iq,Id




作者: 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-4-21 18:18 编辑

状态 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以下。高于此转速才判断是否同步。

拖动电流增减量 PULL_Current_Inc_f12 :轻载时工作电流较小,若拖动电流较大不降低,转速要加到较快才能同步。拖动两三圈以后(重载已同步)减电流,轻载能尽早切同步。
拖动电流下限取值可按上限的1/2到 1/8 之间,  在状态4 代码中确定,主要是为了轻载能在低速同步,不必拖动到较高转速才能同步,此代码中用的  CURRENT_Pull_Max_f12/8



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

状态 4 起转波形


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

作者: Angus    时间: 6 天前
本帖最后由 Angus 于 2024-4-30 09:36 编辑

状态 3 快速起转的流程。



拖动起始电压,和起始转速,在跳转到状态 3 之前赋值,如下图 394~397 行。
394行初始电压的确定依据是,让轻载能转动即可。
397行拖动起始转速,可参考拖动转速下限值。


在状态 3,电压逐步增加到 248行给定值——拖动最大电压值,这个电压值的确定依据是:即使不转,也不会过流,电流=电压/(电阻+电抗)。

若 248 行的电压值,写成和 394 行一样的初值,可验证 394 行的初值能否让轻载转得动。


位置收敛后角度 Angle_q 加快调整,接近估算角度时,就可以同步转了。代码并未立即切同步,而是保持在状态 3 继续执行一段时间,到电压增加到指定值,并且再 L/R 时间后——电流和转动都稳定了——再切同步。

可以切同步但未切同步的时段,是准同步状态,可适当提高一点电压,以提高转速,让转动更稳定。这个电压值是 234 行设定的。







作者: Angus    时间: 6 天前
本帖最后由 Angus 于 2024-4-27 11:00 编辑

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

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


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


作者: Angus    时间: 前天 10:00
本帖最后由 Angus 于 2024-4-30 13:00 编辑

为保证切到同步后能可靠保持同步转动,除了角度收敛,一般还需其它条件,才切同步。比如转速已高于能同步转的最低转速。
我们采用的方法是,在某个电压下能稳定转动一会儿。

起动时若能执行到235行,表明 Angle_q 与估算 Q 轴之间的角度偏差已很小。如果输出电压已增加到 234 行的值(转速与电压基本成正比,但有滞后),还能反复执行到此——Angle_q 角度始终保持在估算 Q 轴附近,那就可以切同步了。




当然,也可以改为用实际转速值 RPM_Measure 是否高于某个下限,来决定是否最终要切同步。





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