wstcllx 发表于 2020-12-7 13:51

使用FPGA实现PID 并用modelsim仿真

<div class='showpostmsg'><p>使用单片机非常常用。但是在FPGA中,由于浮点运算问题。使用PID就优点麻烦。</p>

<p>下面是我设计的一个PID的Verilog程序。模拟16bitDAC和ADC的PID闭环。在运算时通过将数据左右。提高了FPGA PID控制精度。</p>

<p>以下时代码和仿真结果。</p>

<pre>
<code>//PID.V
moduledemo_top(
        //system signals
        input        clk                                                , // 时钟信号
        input        rst_n                                        , // 复位信号,低电平有效
        input        signed                 target        , // 目标值
        input        signed                    y        , // 实际输出值
        output        signed       PID_OUT          // pid输出值
);

parametersigned Kp = 32'd8;
parametersigned Ki = 32'd16;
parametersigned Kd = 32'd4;

wire signedek0; // e(k)
regsignedek1; // e(k-1)
regsignedek2; // e(k-2)
wire signedd_uk;// pid增量
regsigneduk1 ; // 上一时刻u(k-1)的值
regsignedPID_OUT_REG = 15'd0;
always @ (posedge clk or negedge rst_n) begin
        if(!rst_n) begin // 初始化误差值
                ek1 &lt;= 31'd0;
                ek2 &lt;= 31'd0;
                uk1 &lt;= 31'd0;
                PID_OUT_REG &lt;= 15'd0;
        end        
        else begin
          PID_OUT_REG &lt;= PID_OUT_REG + d_uk;
          ek2 &lt;= ek1; // 再延时一个时钟周期,得到e(k-2)
                ek1 &lt;= ek0; // 延时一个时钟周期,得到e(k-1)
        end          
end

assign ek0= {(target - y),16'd0}; // 计算e(k)
assign d_uk = (ek0 -ek1)/Kp + ek0/Ki + ((ek0 - ek1)-(ek1 - ek2))/Kd; // 计算pid增量
assign PID_OUT = PID_OUT_REG;

endmodule</code></pre>

<pre>
<code>//pid_tb.v
`timescale 1ns/1ps
module pid_tb ();

reg clk;
reg rst_n;
reg signed                 target        ; // 目标值
reg        signed                    y        ; // 实际输出值
wire signed           uk0;// pid输出值

reg i;
reg signedmytxt;
reg signed adc = 16'd0;
initial
begin
        clk = 1'b0;
        rst_n = 1'b1;
        #5 rst_n = 1'b0;
        #5 rst_n = 1'b1;
        target = 16'd800;
adc= 16'd0;
end

always #5 clk = ~clk;

always @ (negedge clk or negedge rst_n) begin
        if(!rst_n) begin // 初始化误差值
                i &lt;= 15'd0;
                y &lt;= 15'd0;
                mytxt &lt;= 15'd0;
        end        
        else begin
          if(i&gt;8)y &lt;= mytxt;//模拟控制输出。
                  else y &lt;= i;
                    mytxt &lt;= uk0;
                    i &lt;= i + 1;
        end          
end

demo_top demo_top_tb(.clk(clk),
                                       .rst_n(rst_n),
                                       .target(target),
                                       .y(y),
                                       .PID_OUT(uk0)
                                       );   

endmodule


</code></pre>

<p></p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

freebsder 发表于 2020-12-7 18:56

<p>看不懂,纯支持了。</p>

wstcllx 发表于 2020-12-8 10:28

freebsder 发表于 2020-12-7 18:56
看不懂,纯支持了。

<p>懒,没写原理。错别字也多。<img height="48" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/congra.gif" width="48" />当自己备用吧</p>

郝旭帅 发表于 2020-12-8 19:35

<p>支持一波</p>

wangrou 发表于 2021-3-26 10:11

郝旭帅 发表于 2020-12-8 19:35
支持一波

<p>支持,能问一下pid控制输出uk和pwm脉冲之间的关系吗</p>

ayay33 发表于 2021-12-22 10:38

<p>这也太好了,支持支持,感谢楼主的无私分享。</p>

伤心小羊 发表于 2024-5-25 15:00

<p>可以分享一下mytxt的数据吗</p>

<p>&nbsp;</p>
页: [1]
查看完整版本: 使用FPGA实现PID 并用modelsim仿真