积分分离pid控制的verilog程序,请帮助修改。<br>
<br>
小弟刚接触eda,现在在进行毕业设计,方向是用FPGA控制直流电机,进行点位控制。我的FPGA时钟为48MHZ(CLK1),系统采样周期为50KHZ(CLK2),所以要使用两个时钟。刚编的pid控制的verilog程序,采用积分分离方式,m是视场切换指令,现在问题多多,请各位高手帮忙修改。<br>
万望各位大侠拉小弟一把 ,切切! <br>
积分分离的方法:在开始时不进行积分,直至偏差达到一定之后才进行积分。即人为设定一阀值 >0。当∣e(k)∣> 时,也即偏差值比较大时,采用PD控制,封闭积分作用。当∣e(k)∣≤ 时,也即偏差值∣e(k)∣比较小时采用PID控制,启用积分作用。<br>
<br>
问题1:kp=1.1, ki=0.0286, kd=10.2是小数应该如何处理? 问题2:为何即使将kp、 ki 、kd都改成整数,综合还是不能通过?问题2:为何综合时RTL原理图看不到CLK1端口和pcur端口,两个时钟应该如何处理?<br>
<br>
<br>
module pid(<br>
rst,clk1,clk2,m,pcur, //input<br>
uout,dataout<br>
); //output<br>
input rst,clk1,clk2;<br>
input[7:0] m; //m 是目标选择指令<br>
input[11:0] pcur; //pcur 是当前位置<br>
output[11:0] uout;<br>
output[7:0] dataout;<br>
reg[11:0] u,u1;<br>
reg[11:0] e0,e1,e2;<br>
reg[11:0] q0,q1,qa,qb; //q2=kd<br>
reg[11:0] e0_b,ek;<br>
reg[11:0] ke;<br>
reg[23:0] w1,w2,w3;<br>
reg[23:0] b1,b2,b3,b4,b5;<br>
reg[11:0] w3_a,b5_a;<br>
reg[11:0] uout;<br>
reg[7:0] dataout;<br>
wire[11:0] p1_b, p2_b,pcur_b;<br>
parameter r=400, p1_a=12'b100100000000, <br>
p2_a=12'b000100000000, //p1_a,p2_a是两个目标位置的原码 <br>
kp=141,ki=4,kd=1292; // kp=1.1, ki=0.0286, kd=10.1先乘128取整<br>
<br>
assign p1_b = ~p1_a+1;<br>
assign p2_b = ~p2_a+1;<br>
assign pcur_b = ~pcur+1;<br>
<br>
always@( posedge rst ) //initial<br>
if(rst==1'b1) <br>
begin<br>
u <= 0;<br>
u1 <= 0;<br>
e0 <= 0;<br>
e1 <= 0;<br>
e2 <= 0;<br>
dataout <= 0;<br>
end<br>
<br>
always@( posedge clk2)<br>
begin<br>
case(m)<br>
1'b0 : begin<br>
e0 =p1_b - pcur_b; //计算目标1与当前位置的差值<br>
if (e0[11]==1)<br>
e0_b = ~e0+1;<br>
else e0_b = e0;<br>
end<br>
1'b1 : begin<br>
e0 = p2_b - pcur_b; //计算目标2与当前位置的差值<br>
if (e0[11]==1)<br>
e0_b = ~e0+1;<br>
else e0_b = e0;<br>
end<br>
endcase<br>
end<br>
<br>
always@( posedge clk1 ) <br>
begin <br>
if (e0_b>r) //pd<br>
begin<br>
ek = e0-e1; <br>
w1 = kp*e0; <br>
w2 = kd*ek; <br>
w3 = w1+w2; <br>
w3_a=w3/128; // 除128还原其应有的值<br>
u = u1+w3_a; <br>
end<br>
else //pid<br>
begin<br>
ke = ki+kd; <br>
q0 = kp+ke; <br>
qa = (-1)*kp; <br>
qb = (-2)*kd; <br>
q1 = qa+qb; <br>
b1 = kd*e2; <br>
b2 = q1*e1; <br>
b3 = b1+b2; <br>
b4 = q0*e0; <br>
b5 = b3+b4; <br>
b5_a = b5/128; // 除128还原其应有的值<br>
u = u1+b5_a; <br>
end<br>
end<br>
<br>
always@(negedge clk2) <br>
begin<br>
uout<=~u+1; //link to DAC<br>
u1 <= u; //将u、e1、e0 的值赋给u1、e2、e1以进行下一次计算<br>
e2 <= e1;<br>
e1 <= e0;<br>
end<br>
<br>
endmodule |