zoukankan      html  css  js  c++  java
  • PID控制算法的c语言实现 附录1 如何让UK值与PWM占空比值对应

     

    看到有不少人问到底如何让UK值与PWM占空比值对应,进而实现占空比输出和输出控制电压对应。

    (注意,我这里讨论的前提是输出控制的是电压,不是PWM方波。PWM输出后要经过滤波整形再输出控制。)

    前提条件:

    输出电压控制电压范围是0-10V。

    给定、反馈、输出电压采样输入电压范围是0-5V(经过运放)。

    使用单片机AD为10位AD芯片。

    那么10位AD芯片电压采集得到的数据范围就是0-1024。

    PWM为 8位可调占空比方波,0对应输出占空比为0的方波,255对应输出占空比100%的方波,127对应输出50%的方波。

    比如当前给定是2.5V,反馈电压是1V。(KP,KI,KD等系数略,关于PID算法的整数实现我在前文中有论述如何实现)。

    那么经过AD采样

    1、给定2.5V对应为 512

    2、反馈1V对应为 205

    假定经过PID计算得到的UK为400

    也就意味着输出电压应当为(400*(UPWM峰值电压))/1024

    那么UK对应的PWM占空比是多少呢?

    我们知道,UK=1024对应占空比为100,也就是PWM的占空比系数为255。可知,PWM系数 = UK/4;

    那么400就应当对应系数 400/4=100。

    也就是输出电压=400*10/1024=3.9V

    同时,由于采样精度以及PWM输出占空比精度控制的问题,将导致输出电压和期望值不是那么线性,所以,我在项目内加入了输出电压采样的控制。

    采样AD输入为0-5V,所以,对于输出0-10V有一个缩小的比例。

    输出10V则采样值对应为255

    输出5V则采样之对应127

    可知,3.9V对应AD结果为97

    采样输出电压值,可以针对性的调整一下占空比输出,从而得到误差允许范围内的一个控制输出电压。

    同时,经过一些加速控制的手段。可以比较迅速的达到控制的目的。

    下文中的UK控制方法是针对增量式PID控制而来做的。

    /****************************************************/

    void    PWMProcess(void)

    {

        uint16 idata temp;

        uint16 idata UKTemp;

     temp = 0;

        UKTemp = 0;

        if( Pwm.ChangeFlag_Uint8 != 0 )   //判断是否需要改变占空比

     {                  //是否需要改变占空比和你的被控系统特性有关

         Pwm.ChangeFlag_Uint8 = 0;

      UKTemp = PID.Uk_Uint16 + SwIn.AddValue_Uint16;  

     //计算UK控制量

     //控制量和计算值以及一个开关量有关,我这里的开关量是系统需要的时候叠加在控制量上的一个变量。

      if(UKTemp>999)

      {

                UKTemp = 999;

      }

    //这里只所以是999封顶而不是1024是因为我的系统PWM的峰值电压是12V导致。

            while(1)                        //如果输出电压和期望电压相差 Delta,则继续调整占空比,直到在误差以内

            {

          ADChPro(UPWMADCH);          //测量输出电压

       if( ADPool.Value_Uint16[UPWMADCH] == UKTemp)

       {

                    return;

       }

       if( ADPool.Value_Uint16[UPWMADCH] > UKTemp)   //如果当前电压大于输出电压,减小占空比

       {

           if( ( ADPool.Value_Uint16[UPWMADCH] - UKTemp ) > UDELTA )

        {

            temp = ADPool.Value_Uint16[UPWMADCH] - UKTemp;  //

         temp = temp / 2;       //下降可以加速下降,所以下降参数加倍

         if( Pwm.DutyCycle_Uint8 > temp )

         {

                            Pwm.DutyCycle_Uint8 = Pwm.DutyCycle_Uint8 - temp;

         }

         else

         {

                            Pwm.DutyCycle_Uint8 = 0;

         }

        }

        else

        {

                        return;

        }

       }

       else           //如果当前电压小于输出电压

       {

           if( ( UKTemp - ADPool.Value_Uint16[UPWMADCH] ) > UDELTA )

        {

            temp = UKTemp - ADPool.Value_Uint16[UPWMADCH];

         temp = temp / 4;  //上升处理不要超调,所以每次只+一半

         if( (255-Pwm.DutyCycle_Uint8) > temp )

         {

                            Pwm.DutyCycle_Uint8 += (temp/2);

         }

         else

         {

                            Pwm.DutyCycle_Uint8 = 255;

         }

        }

        else

        {

                        return;

        }

       }

                DisPlayVoltage();

                PWMChangeDuty(Pwm.DutyCycle_Uint8);  //改变占空比

       Delay(10,10);

     

            }

     }

    }

    /*****************************************************/

  • 相关阅读:
    Redis配置不当可导致服务器被控制,已有多个网站受到影响 #通用程序安全预警#
    Webstorm10.0.3破解程序及汉化包下载、Webstorm配置入门指南
    用Log Parser Studio分析IIS日志
    使用SQL语句创建和删除约束
    MVC Controller 基类中的Request
    Entity Framework 4.1 绕过 EF 查询映射
    Bash脚本编程学习笔记09:数组
    CentOS 7上的系统管理之:Systemd和systemctl
    Linux是如何启动的?
    CentOS 7上的进程管理
  • 原文地址:https://www.cnblogs.com/ITGUANCHAZHE/p/14319744.html
Copyright © 2011-2022 走看看