asdmaill 发表于 2013-9-21 15:02:25

BLDC的双闭环老调不好,求帮助

速度环和电流环调了好几天了,老是有问题,要么稳态偏差大,要么就振荡,片子是33FJ64MC508A,目前外部晶振为7.3728M,经PLL后得到16588800Hz的系统时钟,弄这个频率,主要是为了方便和VB6.0做串口通信,观察PID数据曲线的波特率为115200,我是1.25MS算一次速度环,算5次后算一次电流环,速度环的PID结果不作任何处理,直接作为电流环的设定值,占空比更新是在电流环里进行,刚开始请教别人说是算若干次电流环然后算一次速度环,我照这个思路来发现电机速度启振荡没法控制,然后我就改为算5次速度环才算一次电流环,这样情况有所好转,但老是有较大的稳态偏差,能从几十转/分跳到100多转/分,有时又能将速度锁定在几转/分之内,压缩包里是我的程序,做过的大侠帮我看看有哪里没对,也希望对新手有所帮助,当然我自己也是新手,共同进步哈{:lol:}

气球 发表于 2013-9-21 16:02:56

{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}

asdmaill 发表于 2013-9-21 16:21:47

楼上的朋友,能帮帮忙吗

asdmaill 发表于 2013-9-22 09:59:03

没人帮忙,自己顶一下

wtliu 发表于 2013-9-22 11:27:43

应该是内环优先,而且要先调内环后调外环。对电机而言PI参数书上有推荐可以在这个值附近调。

asdmaill 发表于 2013-9-22 11:31:14

谢谢楼上的,我现在就是先调内环电流,然后调外环速度,但速度振荡的不行

asdmaill 发表于 2013-9-22 11:33:17

//----------------------------------------------------------------------
//速度闭环PID计算程序
//----------------------------------------------------------------------
void Speed_Pid(void)
{   
    //DesiredSpeed = Motor_Speed/14;
    if(Speed >= DesiredSpeed)    //计算偏差
    {
       SpeedError = Speed - DesiredSpeed;//测量值大于给定值
       Flags.Speed_error_dir = 1;          //偏差为负数
    }
    else
    {
       SpeedError = DesiredSpeed - Speed;//给定值大于测量值
       Flags.Speed_error_dir= 0;         //偏差为正负数
    }      
    Txbuff = SpeedError >>8; //将速度偏差值存入发送缓存
    Txbuff = SpeedError & 0x00FF;
    //Speed = 0x0000;   //得到偏差后,将测量到得数据清空

    if(Flags.Speed_error_dir ==0)    //偏差为正数,则积分数据和偏差相加
    {
       SpeedIntegral = SpeedIntegral + SpeedError;//对偏差进行积分
    }

    else//偏差为负数,则积分数据和偏差相减
    {
          if(SpeedIntegral>=SpeedError)//积分大于偏差
          {
             SpeedIntegral = SpeedIntegral - SpeedError;
          }
          else //偏差大于积分
          {
             SpeedIntegral = SpeedError - SpeedIntegral;
          }
    }
         
    if(SpeedIntegral >2000)//积分限幅
       {
         SpeedIntegral = 2000;
       }
    Speed_PID = (SpeedError + SpeedIntegral*0 )/100;
    Txbuff = Speed_PID >>8;//将电机速度PID数据存入发送缓存
    Txbuff = Speed_PID & 0x00FF;
这是速度环的代码

//----------------------------------------------------------------
//电流闭环PID计算程序
//----------------------------------------------------------------
void Current_Pid(void)   
{   
    DesiredCurrent = Speed_PID;    //将速度环输出转换为电流环输入
    if(Current >= DesiredCurrent)   //计算电流偏差
    {
         CurrentError = Current - DesiredCurrent;//测量值大于给定值
         Flags.Current_error_dir = 1;            //偏差为负
    }
    else
    {
         CurrentError = DesiredCurrent - Current;//给定值大于测量值
         Flags.Current_error_dir= 0;               //偏差为正
    }      
    //Current = 0x0000;   //得到偏差后,将测量到的数据清空
    if(Flags.Speed_error_dir ==0)    //根据偏差方向,决定积分数据和偏差是相加还是相减
    {   
       CurrentIntegral = CurrentIntegral + CurrentError;//对偏差进行积分
    }
    else
    {
       if(CurrentIntegral>=CurrentError)
       {
          CurrentIntegral = CurrentIntegral - CurrentError;
       }
       else
       {
          CurrentIntegral = CurrentError - CurrentIntegral;
       }
    }               
    if(CurrentIntegral >2000)//积分限幅
       {
         CurrentIntegral = 2000;
       }
    Current_PID = (CurrentError + CurrentIntegral/20 )/20;
    if(Flags.Speed_error_dir==0)
    {
       if(DutyCycle >= 65000)
       {
          DutyCycle = 65535;
       }
       else
       {
          DutyCycle = Current_PID + DutyCycle;    //电机加速
          if(DutyCycle >=65000)
          {
             DutyCycle = 65535;
          }
       }
    }
    else                                        ////电机减速
    {
       if(DutyCycle >= Current_PID)
       {
          DutyCycle = DutyCycle - Current_PID;
       }
       else
       {
          DutyCycle = Current_PID - DutyCycle;
       }
    }
    PDC1 = DutyCycle;
    PDC2 = PDC1;
    PDC3 = PDC1;
    Txbuff = DutyCycle >>8; //将电机占空比数据存入发送缓存
    Txbuff = DutyCycle & 0x00FF;            
   这是电流环的代码

asdmaill 发表于 2013-9-22 11:42:19

//------------------------------------------------------------------
//T2中断处理程序
//------------------------------------------------------------------
void __attribute__((interrupt,no_auto_psv)) _T2Interrupt( void )
{
    IFS0bits.T2IF = 0;            //清零标志
    led1 = ~led1;
    Pid_Count++;
    if(Flags.RunMotor == 1)
    {
       if(Pid_Count ==1)
       {
          Speed_Pid(); //计算速度环
       }
       else
       {
          Current_Pid(); //计算电流环
          if(Pid_Count ==10)
          {
            Pid_Count = 0;
          }
       }
    }
}
这个是T2中断,每5ms算一次速度,每0.5ms算一次电流

asdmaill 发表于 2013-9-22 11:49:59

是不是我PID程序本身就有问题,我对PID控制原理没理解对?我老感觉是哪没对,但又不知道是哪里

mtswz.213 发表于 2013-9-22 12:17:33

你这个有问题嘛!电流环控制周期肯定要比速度环快了,最好是跟PWM周期一样,先把电流环调好再调速度环,电流环调不好都是白搭!

linguicheng 发表于 2013-9-22 12:25:48

10楼的说的很对,先处理电流环,如果电流环不好其他的也难说;其次是速度环,在做速度环时稳速的范围要明确,不然会回来振荡;对于速度环的滤波可以考虑一下采用霍尔6次滤波方式(123456/6;234567/6;345678/6---),这样电机的霍尔跟随性好。

linguicheng 发表于 2013-9-22 12:29:30

还有在做稳速时,特别是启动时电机会振荡(也就是惯性产生的),可以采用如设定3000转,PWM为80%,这时要设一个惯性值防止PWM减的太低(80%*0.6或0.7)这个效果要具体根据电机而定,这样有振荡也就只有一次,而且振荡幅度也小。你可以试试;

asdmaill 发表于 2013-9-22 14:04:27

感谢两位的帮助,那就我的PID程序本身来说,有没有不对的地方呢

asdmaill 发表于 2013-9-22 14:16:12

linguicheng 发表于 2013-9-22 12:29 static/image/common/back.gif
还有在做稳速时,特别是启动时电机会振荡(也就是惯性产生的),可以采用如设定3000转,PWM为80%,这时要设 ...

这位朋友所说的霍尔六次滤波方式,不知道是做什么用的啊,目的是什么呢,让采集到得速度数据更稳?

K.O.Carnivist 发表于 2013-9-22 15:34:57

楼主用的什么样的电机呢?我感觉ms级别的电流环很慢。控制周期至少应该比电流的变化时间快。

asdmaill 发表于 2013-9-22 15:43:55

57的三相无刷,空载电流200mA,额定电流5A,24V电压

linguicheng 发表于 2013-9-24 12:02:05

霍尔六次递进滤波方式,目的是让采集到得速度数据更稳,现在我们的产品就是这样做的,用起来跟随性也比较好。

linguicheng 发表于 2013-9-24 12:02:59

电流环肯定要达到US级,速度环要达到MS级;这样应该可以。

asdmaill 发表于 2013-9-25 11:27:07

你好,你说的霍尔6次递进滤波,是怎么实现的呢,能说说吗

v0932313 发表于 2013-10-15 10:30:45

如果我不需要速度环,速度设置为开环,电流环的基准应该怎么设置?特别是在负载变动的情况下?

v0932313 发表于 2013-10-21 13:21:37

asdmaill 发表于 2013-9-22 11:33 static/image/common/back.gif
//----------------------------------------------------------------------
//速度闭环PID计算程序
//--- ...

你的双闭环调试好了吗?能不能加QQ交流一下?我的QQ6824832

asdmaill 发表于 2013-10-21 13:38:51

还在调试之中,你也在做这个吗,你做的怎么样了呢,我用的是DSPIC33FJ,不知道你用的是什么片子

莫伊及 发表于 2013-11-20 18:05:32

一般单闭环就可以叫速度很稳了。我一直觉得做双闭环就是为了显示能力的

zqbing 发表于 2013-11-20 18:49:33

楼主你说的震荡波形是怎样的,相线上的吗,有图吗

ljh407055315 发表于 2013-12-30 20:36:14

学习一下 看看

ersha4877 发表于 2014-1-30 17:12:23

学习下{:smile:}

not_at_all 发表于 2014-1-31 11:04:29

莫伊及 发表于 2013-11-20 18:05
一般单闭环就可以叫速度很稳了。我一直觉得做双闭环就是为了显示能力的

同感   话说变化不大的负载只需要速度环就够了,负载经常突变的情况才需要电流环

huangxiaowei 发表于 2014-4-16 15:13:13

   顶一下

robin林 发表于 2014-9-20 13:22:56

linguicheng 发表于 2013-9-22 12:25
10楼的说的很对,先处理电流环,如果电流环不好其他的也难说;其次是速度环,在做速度环时稳速的范围要明确 ...

理解了六次递进滤波算法了那我对比下自己的 原来是上次滤波,,,你好你对电流环滤波有啥高见 能否给个建议

xyx2012xyx 发表于 2014-9-20 13:43:15

收藏下,对这个算法不太了解

linguicheng 发表于 2014-9-24 12:31:02

电流滤波,我们是采用二路电流采样法。平均电流这路:也是采用6次滤波方式(采样时取得平均电流后)将6次的平均电流再做平均;峰值这路采用PID算法来控制;为了就是得到稳定的电流曲线。

linguicheng 发表于 2014-9-24 12:32:08

电流环要采用微秒级,不然咸觉速度就慢了。

dianzidianzi 发表于 2014-12-13 14:09:01

电流环控制正确是关键点

Ray______ 发表于 2014-12-14 08:07:24

新手感谢资料,看评论涨知识

fxhfxh 发表于 2014-12-19 19:20:25

楼主这个事情搞好了没有呀。最近也准备要搞这个东西了。

fhslh 发表于 2014-12-19 20:31:13

发现坛上最近好多人搞bldc,难道要爆发了

rom 发表于 2014-12-29 04:07:49

做个记号,六次滤波很好

robincui 发表于 2014-12-30 13:44:45

最近准备做高速电机的BLDC驱动,有参考价值

小东yds 发表于 2015-1-9 18:40:33

你好,请问你的电流环是怎么闭合的?采集的是母线电流吗

xcrane 发表于 2016-10-16 16:37:17

霍尔六次滤波方式,听起来好高大上,记录一下!

stm32_bldc 发表于 2016-12-8 13:52:51

mtswz.213 发表于 2013-9-22 12:17
你这个有问题嘛!电流环控制周期肯定要比速度环快了,最好是跟PWM周期一样,先把电流环调好再调速度环,电 ...

兄弟,请教下电流环的电流采样是在哪个时机最好呢

mtswz.213 发表于 2016-12-8 14:33:16

stm32_bldc 发表于 2016-12-8 13:52
兄弟,请教下电流环的电流采样是在哪个时机最好呢

pwm的上溢中断是最好的,我用tms320f28062电流采样都是在pwm上溢自动触发adc采样,不过要看载波了,载波低,可以在一个周波采样两次,触发两次中断,电流环算两次,不过我们在2k载波以下才用双更新!

stm32_bldc 发表于 2016-12-8 15:03:30

mtswz.213 发表于 2016-12-8 14:33
pwm的上溢中断是最好的,我用tms320f28062电流采样都是在pwm上溢自动触发adc采样,不过要看载波了,载波 ...

我用的是六步方波的,频率16K,在PWM有效期间的中点采样,用的滑动平均滤波,空载的时候,电流较小,占空比给大给小采样的电压没什么区别,我们电路设计10A才能对应ADC值500,你说的pwm上溢是不是PWM周期中断呢,能加你QQ请教下吗

dingding618 发表于 2017-1-6 14:02:05

电流环建议用个阻感负载去调。调电流环是VREF不能给太大。我平时都是两个环一起调的,在速度环加个限幅,不要让电流太大。
页: [1]
查看完整版本: BLDC的双闭环老调不好,求帮助