找回密码
 立即注册
楼主: 梁工

三相无刷直流电机驱动-STC8H-STC32G-无HALL 改进启动算法,启动可靠

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:410
  • 最近打卡:2026-07-21 09:39:09

83

主题

7972

回帖

1万

积分

超级版主

积分
17025
发表于 2026-1-3 18:24:17 | 显示全部楼层
dnxk*** 发表于 2026-1-3 18:11
是我硬件电路设计问题,pmos管栅极上拉电阻太大了,导致关断时候放电太慢,关断时间太长,上下管互通。上 ...

明白,所以设计时要选取合适的电阻,可以示波器看看其速度。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2026-03-27 15:49:45
已绑定手机

1

主题

3

回帖

27

积分

新手上路

积分
27
发表于 2026-3-24 11:33:52 | 显示全部楼层
梁工,我驱动高压310V 1300W电机遇到一个问题:静止启动以及调速运转都正常,但是当在停机过程中,电机滑动到即将停止时重启容易失步。这种状况怎么解?如果刚停止,电机还在高速滑动时重启也正常,出问题总是在滑动到较低速度时重启的过程中。

点评

可能是在比较临界的转速,检测到需要碰启动后,增加初始定位的第一个时间值,将电机完全停止再启动,看看。  详情 回复 发表于 2026-3-24 11:44
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:410
  • 最近打卡:2026-07-21 09:39:09

83

主题

7972

回帖

1万

积分

超级版主

积分
17025
发表于 2026-3-24 11:44:33 | 显示全部楼层
Wolf_*** 发表于 2026-3-24 11:33
梁工,我驱动高压310V 1300W电机遇到一个问题:静止启动以及调速运转都正常,但是当在停机过程中,电机滑动 ...

可能是在比较临界的转速时,转速很低,但没有停止,此时启动,由于惯性大,启动失败。检测到需要启动后,增加初始定位的第一个时间值,将电机完全停止再启动,看看。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2026-05-10 08:25:19

0

主题

2

回帖

6

积分

新手上路

积分
6
发表于 2026-5-10 08:25:19 | 显示全部楼层
请教例程用KEIL几打开,在哪里下载STC的KEIL驱动文件,我还没有搞定开发环境

点评

不需要驱动文件的。你添加一下型号和头文件、仿真固件: [attachimg]137312[/attachimg]  详情 回复 发表于 2026-5-10 11:41
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:410
  • 最近打卡:2026-07-21 09:39:09

83

主题

7972

回帖

1万

积分

超级版主

积分
17025
发表于 2026-5-10 11:41:22 | 显示全部楼层
封C*** 发表于 2026-5-10 08:25
请教例程用KEIL几打开,在哪里下载STC的KEIL驱动文件,我还没有搞定开发环境 ...



不需要驱动文件的。你添加一下型号和头文件、仿真固件:

截图202605101141078889.jpg

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:324
  • 最近打卡:2026-07-22 08:34:53
已绑定手机

14

主题

41

回帖

521

积分

高级会员

积分
521
发表于 2026-5-17 15:12:53 | 显示全部楼层
  梁工你好,我现正在学习你发布的三相无刷电机驱动-STC32G-HALL-Ver3程序,有以下几个问题不明白,向你请教一下。
  一、看程序的几种预定位时间设置,小电机在100ms左右,大一点的电机在几百ms,预定位的作用是什么呢?是要先让电机转起来达到多少转吗?

  二、在PWM中断里面的ROLL_CHECK转动检测程序部分,有以下几个问题:
  1.         else if(run_mode == STARTING)        //启动模式, 使用查表S曲线加速启动
  2.         {
  3.                 if(++fs_cnt == 4)        // 使用256点的S曲线表,初速V1(<font color="#ff0000">转/分</font>),终速V2(转/分),加速时间t(ms),fs=24000000/1024/4 = 46875 /8 = 5859Hz,则加速总步数StartTime = t/1000*fs = t*1000/(1024*4/24) = t*375/64=t*6步
  4.                 {                                        // 查表步进 = 65536/StartTime, 步数SartCnt每次+1,查表得到速度系数 du=S_Curve[SartCnt*65536/StartTime/256] = S_Curve[SartCnt*256/StartTime], 当前速度 V = V1 + (V2-V1)*du/1024 (转/秒)
  5.                         fs_cnt = 0;                // 采样频率fs,16位累加器roll_sum,磁极对MPP,则电机转速 V=60*fs*roll_N/roll_sum/MPP, 转速步进 roll_N = V*MPP*sum/60/fs = V*MPP*65536/60/5859 = 0.1864*V*MPP = V*MPP*191/1024
  6.                         SartCnt++;
  7.                         if(SartCnt < StartTime)
  8.                         {
  9.                                 roll_N = BeginSpeed + (u16)(((u32)S_Curve[(u8)((u32)SartCnt*256/StartTime)] *(FinishSpeed - BeginSpeed))/1024);        //当前速度 V = V1 + (V2-V1)*du/1024 = V1 + (V2-V1)*S_Curve[SartCnt*256/StartTime]/1024  (<font color="#ff0000">转/秒</font>)
  10.                                 roll_sum += (u16)(((u32)roll_N*MPP*191) >>10);        // 当前速度 = V*MPP*191/1024
  11.                                 angle = (roll_sum >> 4);        //roll_sum是16位的,SVPWM表长度为12位
  12.                                 LoadPwm();
  13.                         }
复制代码


  1、这里的V1V2V,单位为什么有转/分、转/秒呢?
  2、关于速度系数du,我是这么想的,总长度是256点,总步数是StartTime,那么查表步进就是256/StartTimedu=S_CURVE[SartCnt*256/StartTime,不知道这样理解是否正确,请问你程序中的注释查表步进=65536/StartTime是怎样理解的呢?
  3、电机转速 V=60*fs*roll_N/roll_sum/MPP, 转速步进 roll_N = V*MPP*sum/60/fs = V*MPP*65536/60/5859 = 0.1864*V*MPP = V*MPP*191/1024
  这里应该怎样理解呢?因为我看后面roll_N = BeginSpeed + (u16)(((u32)S_Curve[(u8)((u32)SartCnt*256/StartTime)] *(FinishSpeed - BeginSpeed))/1024)这里是计算转速,而不是步进。
  4、对于roll_sum += (u16)(((u32)roll_N*MPP*191) >>10); //当前速度 = V*MPP*191/1024
      angle = (roll_sum >> 4)
  为什么roll_sum的累加值就是当前电角度angle呢?

谢谢!


点评

一、预定位的作用是什么呢? 电机静止时,无法检测反电动势,只能强制同步拖动,此时直接施加三相交流电给电机,电机同步转动。 但是由静止开始转动的前2~3步很关键,太快的启动会因为惯性(转动惯量)导致  详情 回复 发表于 2026-5-17 22:41
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:410
  • 最近打卡:2026-07-21 09:39:09

83

主题

7972

回帖

1万

积分

超级版主

积分
17025
发表于 2026-5-17 22:41:23 | 显示全部楼层
kpf*** 发表于 2026-5-17 15:12
梁工你好,我现正在学习你发布的三相无刷电机驱动-STC32G-无HALL-Ver3程序,有以下几个问题不明白,向你 ...
一、预定位的作用是什么呢?
    电机静止时,无法检测反电动势,只能强制同步拖动,此时直接施加三相交流电给电机,电机同步转动。
    但是由静止开始转动的前2~3步很关键,太快的启动会因为惯性(转动惯量)导致没法同步拖动,所以要用更慢的速度先让转子转到指定的位置,类似赛跑时的“各就位”。

    预定位时间设置,小电机由于转动惯量很小,启动迅速,所以几十100ms左右就够了,但大的电机特别是带动大的转动惯量,需要几百ms才能转到指定位置,最明显的就是家用风扇40cm的扇叶,基本要500ms才能转到指定位置。
    第一步过后,第二、第三步时间适当递减,实现加速,然后就切入正式的强拖启动。

二、
1、这里的V1、V2和V,单位为转/分,后面的计算结果标注(转/秒)是明显的笔误,应该是转/分,看下面的计算解释。

2、关于速度系数K,S曲线的值就是速度系数K,为了避免小数计算,我用1024表示1。
   加速时,有2种方式:线性加速和S曲线加速,后者效果比较好。
   S曲线是256点的,不管用多长时间加速,都是256点。
   每4个PWM周期处理一次,则处理频率fs=FOSC/1024/4 = 24000000/1024/4 = 5859Hz。
   加速时间为t(ms),对应处理频率周期数 = t/1000 *fs = t*5.859,为了避免浮点计算,取整为 t*6,比如加速时间为1000ms,则要加速6000个周期,这就是我说的“加速总步数StartTime”。

步数StartCnt每次+1,查S曲线表得到速度系数 K=S_Curve[256*StartCnt/StartTime]/1024, 初速V1(转/分),终速V2(转/分),则当前速度 V = V1 + (V2-V1)*K (转/分), /1024是因为S曲线是整数,1024对应1。

3、采样频率fs,16位累加器roll_sum,每次的步进量roll_N,roll_sum累加满65536对应一个电周期,对应处理步数为65536/roll_N,而1秒钟的电周期数即为电子转速=fs/(65536/roll_N)=fs*roll_N/65536,单位为Hz。
磁极对为MPP,则机械转速 V=60*电子转速/MPP = 60*fs*roll_N/65536/MPP,从而可以计算出转速V对应的速度步进量
roll_N = V*MPP*65536/60/fs = V*MPP*65536/60/5859 = V*MPP*0.18642544 = V*MPP*191/1024。
这里的V,就是前面计算的 V = V1+(V2-V1)*K/1024,即程序中的CurrentSpeed。

当前正弦波角度 = 3600*roll_sum/65536; 3600表示角度分辨率为0.1°。

以上解释不知道是否明白?


三相无刷电机驱动-STC32G-无HALL-Ver3.rar 已经更新在主楼,优化了启动程序,启动后可以转去转动检测或直接进入闭环运行。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:324
  • 最近打卡:2026-07-22 08:34:53
已绑定手机

14

主题

41

回帖

521

积分

高级会员

积分
521
发表于 2026-5-18 21:19:16 | 显示全部楼层
梁*** 发表于 2026-5-17 22:41
一、预定位的作用是什么呢?
    电机静止时,无法检测反电动势,只能强制同步拖动,此时直接施加三相交流 ...

感谢梁工的详细解答,在run_mode == STARTING启动模式中还有以下两个疑问再向你请教:
      一、关于roll_N = BeginSpeed + (u16)(((u32)S_Curve[(u8)((u32)SartCnt*256/StartTime)] *(FinishSpeed - BeginSpeed))/1024);
      以0:2212电机参数为例
      #define    BeginSpeed            60        // 启动起始转速,转/分
      #define    FinishSpeed            600        // 启动终了转速,转/分
      这里BeginSpeed、 FinishSpeed应该是机械转速,在上述roll_N的运算中,roll_N每次都是=BeginSpeed+查表得到速度系数换算得来的速度增量,结果是某次fs采样后对应的静态转速,而在梁工你的解答中roll_N是每次采样后的步进量,请问这个怎样理解好呢?

      二、关于16位累加器roll_sum累加满65536对应一个电周期
      PWM每隔42μs中断1次,每中断4次fs采样1次,对应采样间隔为168μs,而fs采样1次roll_sum累加1次,这样roll_sum累加满65536则总共需时168μs*65536=11秒,这里这样换算肯定是不对的,但又不知道错在那里。而且这里采样65536次又没有在程序中看到有计数满值的处理命令。
      按照梁工你最后说的把一个电周期按0.1度分成65536份,这样是好理解的,但与前面的roll_N是每次采样的步进量又对不上了。

      不带霍尔的电机驱动真的是很难,我对这里的运算部分想了好久都没有弄明白,恳请梁工百忙之中能抽时间解答一下,谢谢!

点评

之前的程序,为了减少变量使用,重复使用了变量roll_N,更新后的程序,不重复使用变量,你就会明白: CurrentSpeed = BeginSpeed + (u16)(((u32)S_Curve[(u8)((u32)StartCnt*256/StartTime)] *(FinishSpeed - BeginS  详情 回复 发表于 2026-5-18 21:50
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:410
  • 最近打卡:2026-07-21 09:39:09

83

主题

7972

回帖

1万

积分

超级版主

积分
17025
发表于 2026-5-18 21:50:08 | 显示全部楼层
kpf*** 发表于 2026-5-18 21:19
感谢梁工的详细解答,在run_mode == STARTING启动模式中还有以下两个疑问再向你请教:
      一、关于rol ...

一、之前的程序,为了减少变量使用,重复使用了变量roll_N,更新后的程序,不重复使用变量,你就会明白:
CurrentSpeed = BeginSpeed + (u16)(((u32)S_Curve[(u8)((u32)StartCnt*256/StartTime)] *(FinishSpeed - BeginSpeed))/1024);        //当前速度 V = V1 + (V2-V1)*K = V1 + (V2-V1)*S_Curve[256*StartCnt/StartTime]/1024  (转/秒)
roll_N    = (u16)(((u32)CurrentSpeed*MPP*191) >>10);        // 当前速度步进 roll_N = V*MPP*65536/60/fs = V*MPP*65536/60/5859 = V*MPP*0.18642544 = V*MPP*191/1024
roll_sum += roll_N;
angle = (u16)(((u32)roll_sum * 3600) >> 16);        //计算当前正弦波角度,roll_sum是16位的,SVPWM表长度为3600
LoadSVpwm();
程序写成这样,应该更容易明白。

二、每一次处理,roll_sum累加一次,但累加的值不是1啊,我举个具体例子:
2212电机:
MPP == 7
BeginSpeed  == 60
FinishSpeed == 600
D_StartTime == 1000
StartTime = D_StartTime*6 = 6000; //StartTime=t*1000/(1024*4/24)=t*375/64=t*6步
假设当前StartCnt == 1000;
CurrentSpeed = BeginSpeed + (u16)(((u32)S_Curve[(u8)((u32)StartCnt*256/StartTime)] *(FinishSpeed - BeginSpeed))/1024);
                    = 60 + (S_Curve[1000*256/6000] *(600 - 60))/1024;
                    = 60 + (S_Curve[42] *540)/1024;
                    = 60 + (35 *540)/1024;
                    = 78;
当前速度为78转/分钟。
roll_N = (u16)(((u32)CurrentSpeed*MPP*191) >>10);
         = 78*7*191/1024;
         = 101;
roll_sum += roll_N;  即 roll_sum += 101。
随着转速增大,roll_N会变得更大,终速600RPM对应 roll_N = 600*7*191/1024 = 783。
65536/783 = 84,即累加84次就够一个正弦波周期了,84/5859=0.014337S,则对应转速 = 60/0.014337/7=598 RPM,验算正确。

无感方波驱动的计算量不算多,FOC驱动的计算量那才叫多。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:324
  • 最近打卡:2026-07-22 08:34:53
已绑定手机

14

主题

41

回帖

521

积分

高级会员

积分
521
发表于 2026-5-20 20:58:08 | 显示全部楼层
梁*** 发表于 2026-5-18 21:50
一、之前的程序,为了减少变量使用,重复使用了变量roll_N,更新后的程序,不重复使用变量,你就会明白:
...

      感谢梁工的耐心回复。
      一、按照梁工你提供的思路,在强拖阶段, 使用256点的S曲线表查到对应的机械转速,而机械转速是由对应频率的交流电产生,机械转速与交流电的频率有对应的关系,这个在程序注释中已作了详细分析。
      二、强拖阶段的交流电是通过SVPWM查表生成,看SVPWM表共4096个点,roll_N按照步进1,一个交流电周期的roll_sum就是4096,放大16倍后就是65536,这个应该就是公式中65536的来源。
      当步进roll_N增大时,交流电的周期减少,频率提高,对应的机械转速也相应提高。
      由于机械转速的时点值与交流电频率有固定关系,查S-Curve表得到的机械转速,通过计算就得到交流电的步进roll_N,roll_sum就是对应的交流电角度,不过由于一个交流电周期的roll_sum放大了16倍,所以计算电角度angle时要用roll_sum/16即右移4位。
      三、关于电角度放大10倍至3600,精度为0.1度,按照梁工你回复中的数据,在机械转速600转时,一个交流电周期的点数只有84点,这样精度0.1度似乎影响不大,提高精度在低转速时的作用应该更大,保证电机运转更平滑。
      以上是我根据梁工你的指引想到的方面,不知道这样理解是否正确呢?谢谢!
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-7-22 09:22 , Processed in 0.079595 second(s), 94 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表