lcwswust 发表于 2025-12-8 10:03:48

关于"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;
                }

      }
}





梁工 发表于 2025-12-8 10:57:20

过0检测原理描述正确,有2个过0点,检测其中一个即可,我习惯检测负半周的过0点。

lcwswust 发表于 2025-12-8 11:00:06

梁工 发表于 2025-12-8 10:57
过0检测原理描述正确。

谢谢梁工

QQ624353765 发表于 2025-12-8 12:43:26

能加我个扣扣吗,想详细了解下624353765

lcwswust 发表于 2025-12-8 13:41:28

QQ624353765 发表于 2025-12-8 12:43
能加我个扣扣吗,想详细了解下624353765

先说说看有啥问题,万一我解决不了就尴尬了。
坛里大神多,总有能解决的;
在论坛里问也挺好的,别人有相同问题也一看就明白了。

QQ624353765 发表于 2025-12-8 15:04:02

lcwswust 发表于 2025-12-8 13:41
先说说看有啥问题,万一我解决不了就尴尬了。
坛里大神多,总有能解决的;
在论坛里问也挺好的,别人有相 ...




为什么要在每个PWM周期内要更新一次PWM波形,是不是频率有点高啊
为什么不需要计算电角度,除了一个过零检测校准下,其他时候都是盲猜
还是加个扣扣吧,好多都没想通624353765

lcwswust 发表于 2025-12-8 16:38:04

QQ624353765 发表于 2025-12-8 15:04
为什么要在每个PWM周期内要更新一次PWM波形,是不是频率有点高啊
为什么不需要计算电角度,除了一个过 ...
你说的都对,每个PWM周期更新一次PWM波形,才能产生正弦波啊,不更新它不就是方波电调了?
这里FOC主打一个正弦驱动,不像方波电调那样6步就完了。
确实是不需要计算电角度、盲猜,原理和方波电调类似;
虽然方波电调在一个周期内会有6次过零,但也可以只采纳其中1次,其它的忽略掉,主要为了省电阻。
相信也有其它人和你一样的想不通,没事,多做实验验证一下。


QQ624353765 发表于 2025-12-8 17:09:07

lcwswust 发表于 2025-12-8 16:38
你说的都对,每个PWM周期更新一次PWM波形,才能产生正弦波啊,不更新它不就是方波电调了?
这里FOC主打一 ...
频率不同步啊,电机转一圈,你的那张spwm表都不知道转了几圈了
他板子上还有两路ADC怎么没用上

lcwswust 发表于 2025-12-8 17:27:04

QQ624353765 发表于 2025-12-8 17:09
频率不同步啊,电机转一圈,你的那张spwm表都不知道转了几圈了
他板子上还有两路ADC怎么没用上
...
确实不同步啊,电角度和机械角度不一样的,有个倍数关系,好像就叫“极对数”,方波电调也一样,一般不会六步就转一圈。

ADC没用上,作为备用,我猜是后面要研究高频注入之类的,或利用MOS管导通电阻作为电流检测之用。

QQ624353765 发表于 2025-12-8 17:40:58

梁工 发表于 2025-12-8 10:57
过0检测原理描述正确,有2个过0点,检测其中一个即可,我习惯检测负半周的过0点。 ...

检测负半周和正半期有区别吗
页: [1] 2 3
查看完整版本: 关于"STC-FOC"之我的猜想