关于"STC-FOC"之我的猜想
参考帖子:“最便宜的 车规-FOC,24万转@STC32G12K128-24A车规,STC-FOC 新算法库,11/30更新”
https://www.stcaimcu.com/thread-19545-1-1.html
最初见到这个电路时,对于只使用4只电阻的过零检测感觉很神奇,但是核心代码是LIB库,
用起来多少会有点不方便,所以想要研究一下原理;
经示波器测试,相线之间的电压波形确实是正弦波,但线电流(以及总线电流)却有周期性的“断点”,
所以猜想其原理就是在UV相的交叉点附近关闭6只MOS管,通过比较器检测“过零”;
基于这种猜想,自己写代码验证了一下,确实可行;只是目前的代码还比较粗糙。
申明:
本程序仅用于研究学习,功能尚未完善,可能有BUG。
此程序仅在1806(KV2280)电机上试过,供电电压5V。
本程序根据帖子中的附件“STC_FAN_FOC库-2025年11月30日 16点46分”修改而来,未使用“STC_FAN_FOC.LIB”库。
产生三相SPWM,在固定相位区间关闭PWM(关断6只MOS管,令三相悬空)便于检测反电势过零点
(U、V相的交叉点,约位于电周期的150度),调节速度mot_speed使过零点的相位达到设定值。
当前配置:
PWM为边沿对齐模式;
PWM频率约23kHz;
PWM占空比最大255,便于用1字节来控制;
SPWM采用查表方式,周期为256;
源代码:
过零检测时机:
参考原理图:“SCH-STC-FOC-24万转-小功率-V1.6-20250910.pdf”
运行环境:
部分核心代码:
//pwm更新中断,约23kHz
void pwma_sr(void) interrupt 26
{
static U8 div=0;
static U8 zp=0,twait=0,zstate=0;
U16 v1,v2,v3,v;
S16 p1,p2,e;
U8 p,c;
PWMA_SR1=0;//清标志
//PTEST^=1;
//----------产生三相SPWM
mot_vp+=mot_speed;
p=mot_vp>>8;//0~255
v1=(U16)SINTAB*set_duty/256+20;
v2=(U16)SINTAB[(p-256/3)&0xFF]*set_duty/256+20;//移相120度
v3=(U16)SINTAB[(p-512/3)&0xFF]*set_duty/256+20;
Foc_Pwm_Swx(v1,v2,v3);
//----------产生三相SPWM
if(mot_state==0)//停止状态
{
pwm_off();
mot_speed=SPEED_START1;
}
else if(mot_state==1)//开环启动
{
pwm_on();
zstate=0;
div++;
if(div>=230)//10ms
{
div=0;
if(mot_speed<SPEED_START2)
{
mot_speed++;
}
else if(p<20)//达到指定速度且在初始相位附近
{
mot_state++;
}
}
}
else if(mot_state==2)//闭环检测
{//在固定的相位区间里关PWM检测反电势并调速
if(zstate==0)//等待达到指定相位关PWM
{
if(p>(256L*(DEGSET-20)/360))//提前20度
{
PTEST=1;
zstate++;
pwm_off();//关PWM,关断6只MOS,
}
}
else if(zstate==1)//等待过零(比较器输出0)
{
c=CMPCR1&1;//比较器输出
if(c==0)//过零
{
PTEST=0;
pwm_on();
zstate++;
//跟据相位差调整电周期,改变速度
v=65536/mot_speed;//电周期,
p1=p;
p2=256L*(DEGSET)/360;
e=p1-p2;//当前相位与目标相位相差
if(e>20)e=20;
if(e<-20)e=-20;
v+=e/2;
//mot_speed=65536/v;
mot_speed-=e;
mot_vp=65536L*DEGSET/360;
}
if(p>=256L*(DEGSET+60)/360)//未等到过零
{
zstate=0;
mot_state=0;
}
}
else if(zstate==2)//等待下一周期
{
if(p<(256L*(DEGSET-10)/360))
zstate=0;
}
}
}
void main(void)
{
......
while(1)
{
if(mot_state==0)//自动重启
{
delayms(1000);
mot_state=1;
}
}
}
过0检测原理描述正确,有2个过0点,检测其中一个即可,我习惯检测负半周的过0点。 梁工 发表于 2025-12-8 10:57
过0检测原理描述正确。
谢谢梁工 能加我个扣扣吗,想详细了解下624353765 QQ624353765 发表于 2025-12-8 12:43
能加我个扣扣吗,想详细了解下624353765
先说说看有啥问题,万一我解决不了就尴尬了。
坛里大神多,总有能解决的;
在论坛里问也挺好的,别人有相同问题也一看就明白了。 lcwswust 发表于 2025-12-8 13:41
先说说看有啥问题,万一我解决不了就尴尬了。
坛里大神多,总有能解决的;
在论坛里问也挺好的,别人有相 ...
为什么要在每个PWM周期内要更新一次PWM波形,是不是频率有点高啊
为什么不需要计算电角度,除了一个过零检测校准下,其他时候都是盲猜
还是加个扣扣吧,好多都没想通624353765
QQ624353765 发表于 2025-12-8 15:04
为什么要在每个PWM周期内要更新一次PWM波形,是不是频率有点高啊
为什么不需要计算电角度,除了一个过 ...
你说的都对,每个PWM周期更新一次PWM波形,才能产生正弦波啊,不更新它不就是方波电调了?
这里FOC主打一个正弦驱动,不像方波电调那样6步就完了。
确实是不需要计算电角度、盲猜,原理和方波电调类似;
虽然方波电调在一个周期内会有6次过零,但也可以只采纳其中1次,其它的忽略掉,主要为了省电阻。
相信也有其它人和你一样的想不通,没事,多做实验验证一下。
lcwswust 发表于 2025-12-8 16:38
你说的都对,每个PWM周期更新一次PWM波形,才能产生正弦波啊,不更新它不就是方波电调了?
这里FOC主打一 ...
频率不同步啊,电机转一圈,你的那张spwm表都不知道转了几圈了
他板子上还有两路ADC怎么没用上
QQ624353765 发表于 2025-12-8 17:09
频率不同步啊,电机转一圈,你的那张spwm表都不知道转了几圈了
他板子上还有两路ADC怎么没用上
...
确实不同步啊,电角度和机械角度不一样的,有个倍数关系,好像就叫“极对数”,方波电调也一样,一般不会六步就转一圈。
ADC没用上,作为备用,我猜是后面要研究高频注入之类的,或利用MOS管导通电阻作为电流检测之用。
梁工 发表于 2025-12-8 10:57
过0检测原理描述正确,有2个过0点,检测其中一个即可,我习惯检测负半周的过0点。 ...
检测负半周和正半期有区别吗