PID算法及其FPGA实现PID控制器结构清晰,参数可调,适用于各种控制对象,PID控制器的核心思想是针对控制对象的控制需求,建立描述对象动态特性的数学模型,通过PID参数整定实现在比例,微分,积分三个方面参数调整的控制策略来达到最佳系统响应和控制效果,式子如下:在数字控制系统中,PID控制规律的实现必须用数值逼近的方法。当采样周期相当时,用求和代替积分、用后向差分代替微分,使模拟PID离散化变为差分方程。式子3.8就是我们的位置式PID算法:下面就是我们要实现上式PID算法。PID的FPGA实现:得到:Verilog实现:viewplaincopytoclipboardprint?.`timescale1ns/1ps.//////////////////////////////////////////////////////////////////////////////////.//Company:.//Engineer:.//.//CreateDate:21:02:5105/14/2014.//DesignName:.//ModuleName:pid.//ProjectName:.//TargetDevices:.//Toolversions:.//Description:.//.//Dependencies:.//.//Revision:.//Revision0.01-FileCreated.//AdditionalComments:.//.//////////////////////////////////////////////////////////////////////////////////.modulepid(.inputclk,.inputrst_n,.input[8:0]error,.outputreg[16:0]uk.);..//reg[16:0]uk;.wire[16:0]uk_wire;.reg[8:0]error_1,error_2;.parameterk0=5;.parameterk1=1;.parameterk2=1;.always@(posedgeclk).begin.if(!rst_n).begin.error_1=0;.error_2=0;.end.else.begin.error_1=error;.error_2=error_1;.end.end..//.reg[14:0]uk1;.always@(posedgeclk).begin.if(!rst_n).begin.uk=0;.uk1=0;.end.else.begin.if((uk_wire17'd15000)&&(uk_wire17'b1000_0000_0000_00000)).begin.uk=17'd15000;.end.else.begin.uk1=uk[14:0];.uk=uk_wire;.end.end.end..wire[14:0]p0;.multu1(..b(k0),..a(error),..p(p0),..clk(clk).);..wire[14:0]p1;.multu2(..b(k1),..a(error_1),..p(p1),..clk(clk).);.wire[14:0]p2;.multu3(..b(k2),..a(error_2),..p(p2),..clk(clk).);..wire[15:0]s1;.addu4(..a(p0),..b(p1),..s(s1),..clk(clk).);..wire[15:0]s2;.addu5(..a(p2),..b(uk1),..s(s2),..clk(clk).);..add2u6(..a(s1),..b(s2),..s(uk_wire[16:0]),..clk(clk).);...endmoduleTestbench:viewplaincopytoclipboardprint?.`timescale1ns/1ps..////////////////////////////////////////////////////////////////////////////////.//Company:.//Engineer:.//.//CreateDate:21:34:2805/14/2014.//DesignName:pid.//ModuleName:J:/xilinx_project/pid/test.v.//ProjectName:pid.//TargetDevice:.//Toolversions:.//Description:.//.//VerilogTestFixturecreatedbyISEformodule:pid.//.//Dependencies:.//.//Revision:.//Revision0.01-FileCreated.//AdditionalComments:.//.////////////////////////////////////////////////////////////////////////////////..moduletest;..//Inputs.regclk;.regrst_n;.reg[8:0]error;..//Outputs.wire[16:0]uk;..//InstantiatetheUnitUnderTest(UUT).piduut(..clk(clk),..rst_n(rst_n),..error(error),..uk(uk).);...initialbegin.//InitializeInputs.clk=0;.rst_n=0;.error=0;..//Wait100nsforglobalresettofinish.#40rst_n=1;.#20error=9'b001111111;.#200error=9'b000111111;.#200error=9'b000011111;.#200error=9'b000001111;.#200error=9'b000000111;.#200error=9'b000000011;.#800error=0;.#200error=9'b111000000;.#200error=9'b111110000;.#200error=9'b111111111;.#800error=0;.//#200error=9'b100000001;..//Addstimulushere..end.always#10clk=~clk;.endmodule中途中mult的实现可以使用LUT或者DSP资源(上一篇博客也有说)另外在modelsim安装和编译xilinx库时,后面那个是在modelsim建立工程才要指定的,我这里是直接从xilinx中启动modelsimse的,(前提是要将xilinx的编译库添加进modelsim)。Project-》designpropertiesEdit-》PreferencesProcess-》ProcessProperties仿真结果:不同于altera-modelsim中,那里是要指定vt文件,然后仿真即可,这里没有指定testbench文件:有几次我鼠标点在uut-pid这里,然后点击simulate,结果可想而知,是不正确的,要点击testbenchtest这个文件,在仿真。为了在modelsim查看波形,format-》anlogy(custom)根据幅值设置一个比较合适的参数。