0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PID控制算法代码 PID控制算法的原理

FPGA研究院 来源:FPGA之旅 2023-07-20 09:23 次阅读

一. 简介

相信大家对于PID控制算法,都不感到陌生了,平衡车就是靠它平衡起来的,还有飞控的平衡算法也是它,以及FOC中的闭环控制中也是用的它,它不仅简单,而且易于理解。那么本篇文章将简要介绍一下算法的原理,然后带大家使用FPGA来实现(C语言实现过程特别简单)。

二. PID算法

PID取自比例、积分、微分三个英文字母的首字母。意味着算法由这三部分组成。

1. P 比例

运算过程为 期望值 减去 当前值 ,然后再乘上一个p系数,就得到了一个反馈值。比例的作用主要是为了让 期望值 与 当前值相等

2. I 积分

将误差值不断累加,然后再乘上一个I系数,就得到了一个反馈值。积分的作用主要是为了消去静态误差,但当前值接近 期望值的时候,这个时候,比例的作用就非常小了,可能会接近于0,而且相邻两次的误差值也近似为0,D微分也起不了多大作用,假如这时候系统外部的阻力和PD反馈值抵消了,这个时候就需要不断的累加这个误差值来使当前值等于期望值

3. D 微分

当前的误差值 减去 上一次运算的误差值,然后再乘上一个d系数,就得到了一个反馈值。微分的作用主要为了减少系统的震荡,在系统变化的方向上,施加一个反方向的反馈,使系统朝这个方向的变化得到抑制

可以到,PID算法主要涉及到三种运算: 加法,减法和乘法。这三种运行在FPGA上也是很容易实现的。

三. FPGA实现

首先需要注意的是,PID的三个系数均为浮点数,为了便于实现,这里将浮点数扩大100倍,然后取整就可以了。然后将反馈的结果缩小100倍就可以了。

1. P 比例实现

实现代码如下,只需要两个时钟周期即可完成。这里通过左移来实现缩小100操作,实际上是缩小了102.倍,不太会影响结果。为了和 I 积分 和 D 微分 运算周期数相同,这里打了一拍操作。

//P -------------------------------------------------
always@(posedge clk or negedge rst_n)
begin
  if( rst_n == 1'b0)
    Kp_fb <= 1'b0;
   else if( pid_en == 1'b1)
       Kp_fb <= ( desired_value - current_value ) * Kp;
   else
       Kp_fb <= Kp_fb;
end


always@(posedge clk or negedge rst_n)
begin
   if( rst_n == 1'b0)
       Kp_fb_reduce <= 'd0;
   else if( cal_delay_0 == 1'b1)
       Kp_fb_reduce <= (Kp_fb >>> 7) + (Kp_fb >>> 9); // /102.4
  else
    Kp_fb_reduce <= Kp_fb_reduce;
end


always@(posedge clk or negedge rst_n)
begin
   if( rst_n == 1'b0)
       Kp_fb_reduce_d0 <= 'd0;
   else if( cal_delay_1 == 1'b1)
       Kp_fb_reduce_d0 <= Kp_fb_reduce;
   else
       Kp_fb_reduce_d0 <= Kp_fb_reduce;


end
//--------------------------------------------------------------------

代码片段:可切换语言,无法单独设置文字格式

2. I 积分实现

实现代码如下,比P比例稍微辅助一点。这里考虑到了一个积分限幅的问题,如果积分值一直累加的话得,可能会导致系统稳定不下来,所以这里设置为3000。

always@(posedge clk or negedge rst_n)
begin
  if( rst_n == 1'b0)
    Ki_integral <= 'd0;
   else if( pid_en == 1'b1)
       if( Ki_integral > $signed('d3000) && ( desired_value - current_value ) > $signed('d0) )
      Ki_integral <= Ki_integral;
       else if( Ki_integral < $signed(-'d3000) && ( desired_value - current_value ) < $signed('d0) )
           Ki_integral <= Ki_integral;
       else
           Ki_integral <= Ki_integral + ( desired_value - current_value );
   else
       Ki_integral <= Ki_integral;
end


always@(posedge clk or negedge rst_n)
begin
   if( rst_n == 1'b0 )
       Ki_fb <= 'd0;
   else if( cal_delay_1 == 1'b1 )
       Ki_fb <= Ki_integral * Ki;
   else
       Ki_fb <= Ki_fb;
end


always@(posedge clk or negedge rst_n)
begin
   if( rst_n == 1'b0 )
       Ki_fb_reduce <= 'd0;
   else if( cal_delay_2 == 1'b1)
       Ki_fb_reduce <= (Ki_fb >>> 7) + (Ki_fb >>> 9); // /102.4
  else
    Ki_fb_reduce <= Ki_fb_reduce;
end


//-------------------------------------------------------------------

代码片段:可切换语言,无法单独设置文字格式

3. D微分 实现

D 微分操作实现如下,按照公式来即可

//D  ---------------------------
always@(posedge clk or negedge rst_n)
begin
  if( rst_n == 1'b0)
    Kd_error <= 'd0;
   else if( pid_en == 1'b1)
       Kd_error <= ( desired_value - current_value );
   else
       Kd_error <= Kd_error;
end


always@(posedge clk or negedge rst_n)
begin
   if( rst_n == 1'b0)
       Kd_fb <= 'd0;
   else if( cal_delay_0 == 1'b1)
       Kd_fb <= (Kd_error - Kd_last_error) * Kd;
   else
       Kd_fb <= Kd_fb;
end


always@(posedge clk or negedge rst_n)
begin
   if( rst_n == 1'b0)
       Kd_last_error <= 'd0;
   else if( cal_delay_0 == 1'b1)
       Kd_last_error <= Kd_error;
   else
       Kd_last_error <= Kd_last_error;
end


always@(posedge clk or negedge rst_n)
begin
   if( rst_n == 1'b0)
       Kd_fb_reduce <= 'd0;
   else if( cal_delay_1 == 1'b1)
       Kd_fb_reduce <= (Kd_fb >>> 7) + (Kd_fb >>> 9); // /102.4
  else
    Kd_fb_reduce <= Kd_fb_reduce;
end
//--------------------------------

代码片段:可切换语言,无法单独设置文字格式

四. 仿真验证

测试代码如下,初始化当前值为500,然后根据期望值和PID输出的反馈值,来调节当前值。

 always@(posedge clk or negedge rst_n) begin
    if( rst_n == 1'b0)
      current_value <= 'd500;
       else if( pid_ack == 1'b1)
           current_value <= current_value + out;
       else
           current_value <= current_value;
   end


PID_Control PID_Control_i(
   .clk            (   clk),
   .rst_n          (   rst_n),


  .pid_en          (   1'b1),
  .pid_ack         (   pid_ack),


   .desired_value  (   desired_value),
   .current_value  (   current_value),


   .Kp             (   'd10),
   .Ki             (   'd1),
   .Kd             (   'd10),
   
   .out            (   out)
);

代码片段:可切换语言,无法单独设置文字格式

仿真波形如下

fe4d3fd6-268c-11ee-962d-dac502259ad0.png

这个是设置了D为0的情况,可以看到系统的震荡

fe7ba24a-268c-11ee-962d-dac502259ad0.png

责任编辑:彭菁

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PID
    PID
    +关注

    关注

    35

    文章

    1446

    浏览量

    83803
  • C语言
    +关注

    关注

    180

    文章

    7530

    浏览量

    128641
  • 控制算法
    +关注

    关注

    4

    文章

    156

    浏览量

    21495

原文标题:FPGA实现PID控制算法

文章出处:【微信号:FPGA研究院,微信公众号:FPGA研究院】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【最新课程推荐】PID控制算法

    本帖最后由 Sanny33 于 2016-10-12 15:32 编辑 课程名称:PID控制算法学习链接:http://t.elecfans.com/1399.html课程介绍:本课程由电子
    发表于 10-12 15:27

    什么是PID控制算法PID控制算法C语言是如何实现的?

    什么是PID控制算法PID控制算法C语言是如何实现的?特殊情况下的
    发表于 06-29 09:24

    PID控制算法的基本思想是什么?PID控制算法是如何形成的?

    常用的控制算法有哪几种?各自有什么特点?PID控制算法的基本思想是什么?PID
    发表于 06-30 06:04

    PID算法代码实现

    目录一. 绪论二. 角度环串级PID原理1. PID基本算法2. 姿态角串级PID原理三. 如何用STM32实现角度-角速度的串级PID
    发表于 08-17 06:44

    PID控制算法的原理是什么

    PID控制算法的原理是什么?PID控制算法有哪些应用?
    发表于 10-11 09:33

    PID控制算法是如何形成的

    常用的控制算法有哪几种?分别有何特点?PID控制算法的基本思想是什么?PID
    发表于 12-21 07:05

    对于PID控制/算法的理解

    补充一下,他们的视频真的把我看哭了以下是对于PID控制/算法的理解、总结:1.PID算法有什么好?首先说为什么要用
    发表于 01-14 08:46

    什么是PID控制算法呢?PID控制算法有何作用

    什么是PID控制算法呢?PID控制算法有何作用?PID
    发表于 02-25 07:36

    PID控制算法仿真与控制

    PID控制算法仿真与控制:了解计算机控制过程,及用不同种高级语言编写实验程序的方法与特点。单回路温度控制
    发表于 07-01 18:25 42次下载

    基于MBP算法PID控制器设计

    针对一般BP 算法存在的不足,提出一种改进的BP 算法,并将其应用于PID 控制器的参数设计中,并且克服了常规的PID
    发表于 08-07 09:42 18次下载

    pid算法_什么是pid算法

    PID控制器是一种最优控制。本文讲述了增量式PID算法原理与数字PID
    发表于 01-01 11:58 1.1w次阅读
    <b class='flag-5'>pid</b><b class='flag-5'>算法</b>_什么是<b class='flag-5'>pid</b><b class='flag-5'>算法</b>

    PID控制算法总结

    本课题是基于 PID 控制算法来进行控制的。在未做这个 课题之前,对于 PID 控制
    发表于 03-09 10:57 1次下载

    PID控制算法控制算法

    PID控制算法控制算法
    发表于 11-17 11:43 10次下载

    第五章:PID控制算法控制算法

    PID控制算法控制算法说明。
    发表于 06-04 14:42 9次下载

    项目二:基于PID控制算法的管热熔机

    基于PID控制算法的管热熔机
    发表于 12-01 09:36 2次下载
    项目二:基于<b class='flag-5'>PID</b><b class='flag-5'>控制</b><b class='flag-5'>算法</b>的管热熔机