使用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 <= 31'd0;
ek2 <= 31'd0;
uk1 <= 31'd0;
PID_OUT_REG <= 15'd0;
end
else begin
PID_OUT_REG <= PID_OUT_REG + d_uk;
ek2 <= ek1; // 再延时一个时钟周期,得到e(k-2)
ek1 <= 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 <= 15'd0;
y <= 15'd0;
mytxt <= 15'd0;
end
else begin
if(i>8)y <= mytxt;//模拟控制输出。
else y <= i;
mytxt <= uk0;
i <= 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> <p>看不懂,纯支持了。</p>
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>
<p>支持一波</p>
郝旭帅 发表于 2020-12-8 19:35
支持一波
<p>支持,能问一下pid控制输出uk和pwm脉冲之间的关系吗</p>
<p>这也太好了,支持支持,感谢楼主的无私分享。</p>
<p>可以分享一下mytxt的数据吗</p>
<p> </p>
页:
[1]