定标,PI调节器的程序实现

在设计出pi调节器后,需要对其离散化,之后存在浮点数,对于整形处理的cpu(如stm32f103)计算压力相当大,本文通过实例讲解,定标处理浮点运算,提高运算的速度。

1.问题的起因

电源开发时,一般会在一个开关周期内采样一次,闭环计算一次。

在一次开发中,选择开关频率是100k,中断时间是10us。那么所有的闭环计算需要在10us中计算完成,否则会引起中断竞争,导致cpu一直在执行中断,无法执行其他的程序,

而设计出闭环调节器后,调节器中难免会出现浮点计算,而对于目前像stm32f103来说,浮点计算压力相当大,实际测试中,也发现要闭环计算PI调节器,花费时间较长,不能在10us内计算完成。

后采用定标后,依旧超过10us,所以只能改成50khz,一个周期是20us,实际测试电压外环和电流内环总共耗时13us左右。

2.离散化

通过matlab计算出电压环的pi参数如下。

Gpi(s)=k*\frac{1+sT}{sT}=0.833381235589746\frac{1+s*0.0008901977751256}{s*0.0008901977751256}

选定采样频率,采用maple使用双线性方式离散化后,如下图

T是采样频率,与开关频率一致,如果使用stm32 使用中央对齐模式,在计数器的峰值采样,可近似得到电流的平均值,本文中是锯齿波,在三角载波的顶点采样,在实际中是电流的谷点。

可得

y_{n}=\frac{b_{0}-b_{1}*z^{-1}}{a_{0}-a_{1}*z^{-1}}=\frac{0.8427429893 -0.8240194818*z^{-1}}{1-1*z^{-1}}

分子上的小数需要保留一定的位数,才能保证离散化后和连续的相近性,在实际中我们尽可能保留多的小数点。

对其进行Q20定标,也就是浮点数乘以2^20.可得蓝色公式的第三行。

3.程序实例

编写离散化后的PI如下:

    uv_k=(Vref-ADC_Value[1] );    //adc 是12位, 
    uv_k = (uv_k<<20)/113;
    //0.8427429893*z-0.8240194818
    //定标Q20
    Yv_k = 883680*uv_k-864047*uv_k_1+Yv_k_1; //Y_k_1,有点积分的意思。//14.72 us
    uv_k_1=uv_k; //当前输入赋值给前一拍,下一拍计算使用
                 
   if(Yv_k>3738339534438400) //6A 数字量是 (1700*2)的Q40定标 最大电流限制在6A中。
       Yv_k= 3738339534438400;
     if(Yv_k<0)
        Yv_k= 0;
    Yv_k_1=Yv_k;//当前输出赋值给前一拍,下一拍计算使用
        
    ui_k=((Yv_k_1>>20)-ADC_Value[2]<<20 ); //3.78us
    ui_k = (ui_k)/633; //633换算成1A
    Yi_k = 28113550*ui_k-27267416*ui_k_1+Yi_k_1; //Y_k_1,有点积分的意思。//14.72 us
    ui_k_1=ui_k; 
             
     if(Yi_k>985162418500000)  //  500 然后Q40定标
          Yi_k= 985162418500000;
      if(Yi_k<10)
           Yi_k= 10;
       Yi_k_1=Yi_k;
          
          tempa = Yi_k>>40;  
          
             if(tempa>896)  //峰值的百分数限幅    
               tempa= 896;
          if(tempa<10)
              tempa= 10;
           
          TIM1->CCR2 = tempa;

程序中,Vref是电压给定,ADC_Value[1]是输出电压的采样值,uv_k是当前的输入量。uv_k_1是前一排的输入量。Yv_k是当前的输出量,Yv_k_1是前一拍的输出量。

 uv_k = (uv_k<<20)/113;此处是对电压的采样值进行了Q20的定标,而/133是将电压装换为真实的电压值,数字量133是电压1V,因为建模的时候,反馈是按照单位反馈。

此处uv_k的定标是为了保留电压的小数点,防止丢失电压的精度。

Yv_k = 883680*uv_k-864047*uv_k_1+Yv_k_1;此处就是递推公式的实现,离散pi的写法。

公式是,

\frac{0.8427429893-0.8240194818*z^{-1}}{1-1*z^{-1}}=\frac{Q20*0.8427429893-Q20*0.8240194818*z^{-1}}{Q20*-Q20**z^{-1}}

按照这样来说,离散化后的数学公式是

Q20*Yv_k = 883680*uv_k-864047*uv_k_1+Q20*Yv_k_1;

而实际程序中,我们为了书写方便, Yv_k=Q20*Yv_k,Yv_k_1=Q20*Yv_k_1;

这样就得到了程序写法:Yv_k = 883680*uv_k-864047*uv_k_1+Yv_k_1;此处的Yv_k_1类似积分的作用,如误差一直存在,则Yv_k_1一直朝着一个方向跑。

 uv_k_1=uv_k; 是当前的输入送给前一拍,下一次计算使用。

if(Yv_k>6597069766656) //6A的Q40定标 最大电流限制在6A中。
       Yv_k= 6597069766656;

此处是对电压环的输出限幅,防止积分过饱和。

此处变为Q40,是因为adc采集的量,和pi的定标都是Q20 二者相加是Q40。

 ui_k=((Yv_k_1>>20)-ADC_Value[2]<<20 ); //3.78us  此处是电压环的输出,经过退标后,还原为Q20,和电流环的反馈做差,送入电流环。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值