您的位置:首页 > 汽车 > 时评 > 陕西购物商城网站建设_邢台信息港人力资源首页_网站功能优化_网站推广策略有哪些

陕西购物商城网站建设_邢台信息港人力资源首页_网站功能优化_网站推广策略有哪些

2025/4/2 16:25:39 来源:https://blog.csdn.net/g_125487/article/details/144354232  浏览:    关键词:陕西购物商城网站建设_邢台信息港人力资源首页_网站功能优化_网站推广策略有哪些
陕西购物商城网站建设_邢台信息港人力资源首页_网站功能优化_网站推广策略有哪些

基于FPGA的PI环调节电压

  • 硬件资源
  • 实验过程
  • 公式分析
  • Verilog代码
    • AD7606控制代码
    • PI环公式模块
    • TOP顶层模块
  • 仿真分析


硬件资源

FPGA开发板
AD7606-AD采样模块
AD9767-DA输出模块

实验过程

默认DA输出初始电压-AD获取DA输入电压-FPGA负责根据目标值进行调节-最终DA输出电压稳定在目标电压附近-改变目标值DA输出随之改变

公式分析

%计算target和meas的误差
error = meas(AD)- target(我都会设置为1.0V)
%通过pi环计算ref值,系数定为:Kp=0.5 Ki=0.05
%先计算积分
integral = integral_prev + δerror
%然后计算需要送出去的值要增加减少多少
δu = Kp * error + Ki * integral
%然后计算出要送出去的值
u(DA_OUT2) = u_prev + δu
%限幅送出去的电压
u(DA_OUT2) = [0.8, 1.2]

Verilog代码

AD7606控制代码


`timescale 1ns / 1ps
module ad7606_if(input                        clk,input                        rst_n,input [15:0]                 ad_data,             //ad7606 datainput                        ad_busy,             //ad7606 busyinput                        first_data,          //ad7606 first dataoutput [2:0]                 ad_os,               //ad7606output reg                   ad_cs,               //ad7606 AD csoutput reg                   ad_rd,               //ad7606 AD data readoutput reg                   ad_reset,            //ad7606 AD resetoutput reg                   ad_convstab,         //ad7606 AD convert startoutput                       ad_data_valid,output reg                   ad_data_valid_temp,output reg [15:0]            ad_ch1,output reg [15:0]            ad_ch2,output reg [15:0]            ad_ch3,output reg [15:0]            ad_ch4,output reg [15:0]            ad_ch5,output reg [15:0]            ad_ch6,output reg [15:0]            ad_ch7,output reg [15:0]            ad_ch8,output reg [3:0]             state
);reg [15:0]  rst_cnt;
reg [5:0]   i;
reg [15:0]   start_count;
//reg [3:0]   state;parameter IDLE=4'd0;
parameter AD_CONV=4'd1;
parameter Wait_1=4'd2;
parameter Wait_busy=4'd3;
parameter READ_CH1=4'd4;
parameter READ_CH2=4'd5;
parameter READ_CH3=4'd6;
parameter READ_CH4=4'd7;
parameter READ_CH5=4'd8;
parameter READ_CH6=4'd9;
parameter READ_CH7=4'd10;
parameter READ_CH8=4'd11;
parameter READ_DONE=4'd12;assign ad_os=3'b000;// oversample
assign ad_data_valid = state == READ_DONE ? 1'b1 : 1'b0;
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginrst_cnt <= 16'd0;ad_reset <= 1'b0;endelse if(rst_cnt < 16'hffff)beginrst_cnt <= rst_cnt + 16'd1;ad_reset <= 1'b1;endelsead_reset <= 1'b0;
endalways@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginad_data_valid_temp<=1'b0;endelse if(ad_data_valid ==1'b1)beginad_data_valid_temp<=1'b1;endelsead_data_valid_temp<=1'b0;
endalways@(posedge clk)
beginif(ad_reset==1'b1)beginstate <= IDLE;ad_ch1 <= 0;ad_ch2 <= 0;ad_ch3 <= 0;ad_ch4 <= 0;ad_ch5 <= 0;ad_ch6 <= 0;ad_ch7 <= 0;ad_ch8 <= 0;ad_cs <= 1'b1;ad_rd <= 1'b1;ad_convstab <= 1'b1;i <= 6'd0;start_count<=16'd0;endelsebegincase(state)IDLE:beginad_cs<=1'b1;ad_rd<=1'b1;ad_convstab<=1'b1;if(start_count==50) beginstart_count <= 16'd0;state<=AD_CONV;endelsestart_count<=start_count+1;endAD_CONV:beginif(i==2) begin                        //wait 2 clocki <= 6'd0;state<=Wait_1;ad_convstab<=1'b1;endelse begini <= i + 6'd1;ad_convstab<=1'b0;       endendWait_1:beginif(i==5) begin                           //wait 5 clocki <= 6'd0;state<=Wait_busy;endelsei <= i + 6'd1;endWait_busy:beginif(ad_busy==1'b0) begin                    //wait busy lowi <= 6'd0;state<=READ_CH1;endendREAD_CH1:beginad_cs<=1'b0;                              //cs validif(i==3) beginad_rd<=1'b1;i <= 6'd0;ad_ch1<=ad_data;                        //read CH1state<=READ_CH2;endelse beginad_rd<=1'b0;i <= i + 6'd1;endendREAD_CH2:beginif(i==3) beginad_rd<=1'b1;i <= 6'd0;ad_ch2<=ad_data;                        //read CH2state<=READ_CH3;endelse beginad_rd<=1'b0;i <= i + 6'd1;endendREAD_CH3:beginif(i==3) beginad_rd<=1'b1;i <= 6'd0;ad_ch3<=ad_data;                        //read CH3state<=READ_CH4;endelse beginad_rd<=1'b0;i <= i + 6'd1;endendREAD_CH4: beginif(i==3) beginad_rd<=1'b1;i <= 6'd0;ad_ch4<=ad_data;                        //read CH4state<=READ_CH5;endelse beginad_rd<=1'b0;i <= i + 6'd1;endendREAD_CH5:beginif(i==3) beginad_rd<=1'b1;i <= 6'd0;ad_ch5<=ad_data;                        //read CH5state<=READ_CH6;endelse beginad_rd<=1'b0;i <= i + 6'd1;endendREAD_CH6:beginif(i==3) beginad_rd<=1'b1;i <= 6'd0;ad_ch6<=ad_data;                        //read CH6state<=READ_CH7;endelse beginad_rd<=1'b0;i <= i + 6'd1;endendREAD_CH7:beginif(i==3) beginad_rd<=1'b1;i <= 6'd0;ad_ch7<=ad_data;                        //read CH7state<=READ_CH8;endelse beginad_rd<=1'b0;i <= i + 6'd1;endendREAD_CH8:beginif(i==3) beginad_rd<=1'b1;i <= 6'd0;ad_ch8<=ad_data;                        //read CH8state<=READ_DONE;endelse beginad_rd<=1'b0;i <= i + 6'd1;endendREAD_DONE:beginad_rd<=1'b1;ad_cs<=1'b1;state<=IDLE;enddefault:state<=IDLE;endcaseendendendmodule

PI环公式模块

代码如下(示例):

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/11/26 12:06:29
// Design Name: 
// Module Name: ad_calculate
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module ad_calculate(input clk,input rst_n,input ad_data_valid,input ad_data_valid_temp,input signed [15:0]            ad_ch1,input signed [15:0]            ad_ch2,input signed [15:0]            ad_ch3,output reg                     cal_mode,output wire                    flag_error,output [15:0]                  data_out  //7863 - 5242);parameter v_1 = 16'd6578;parameter k_p = 16'd50;//*100parameter k_i = 16'd5;//*100reg        ad_data_valid_temp3;reg        ad_data_valid_temp4;reg        ad_data_valid_temp2;reg signed [15:0] error ;reg signed [15:0] delta_error ;reg signed [15:0] error_prev ;reg signed [31:0] integral  ;reg signed [31:0] integral_prev   ;reg signed [31:0] delta_u_t   ;reg signed [31:0] u_t   ;reg signed [31:0] u_t_prev   ;assign data_out=u_t[15:0];always @(posedge clk or negedge rst_n)beginif(!rst_n)begincal_mode<=1'd0;end else if(ad_data_valid==1'b1 && ad_ch1 > $signed('d16383) )begincal_mode<=1'd0;endelse if(ad_data_valid==1'b1 && ad_ch1< $signed('d16383))begincal_mode<=1'd1;endelse begincal_mode<=cal_mode;endendassign flag_error=((ad_ch2>>2)>(ad_ch3>>2))?1:0;always @(posedge clk or negedge rst_n)beginif(!rst_n)beginad_data_valid_temp2<=1'd0;ad_data_valid_temp3<=1'd0;ad_data_valid_temp4<=1'd0;end else beginad_data_valid_temp2<=ad_data_valid_temp;ad_data_valid_temp3<=ad_data_valid_temp2;ad_data_valid_temp4<=ad_data_valid_temp3;endend//计算error  flag_error 1->ad_ch3>1.0v 0->ad_ch3<1.0v always @(posedge clk or negedge rst_n)beginif(!rst_n)beginerror<=16'd0;end else if(ad_data_valid==1'b1 )begin
//            error<=ad_ch3-ad_ch2;error<=-(ad_ch2-ad_ch3);endelse beginerror<=error;endendalways @(posedge clk or negedge rst_n)beginif(!rst_n)beginerror_prev<=16'd0;end else if (ad_data_valid_temp==1'b1 )beginerror_prev<=error;endendalways @(posedge clk or negedge rst_n)beginif(!rst_n)begindelta_error<=16'd0;end else if (ad_data_valid_temp==1'b1 )begindelta_error<=error-error_prev;endelse begindelta_error<=delta_error;endend//    always @(posedge clk or negedge rst_n)begin
//        if(!rst_n)begin
//            integral_prev<=32'd0;
//        end 
//        else begin
//            integral_prev<=integral;
//        end
//     end//    always @(posedge clk or negedge rst_n)begin
//        if(!rst_n)begin
//            integral<=32'd0;
//        end 
//        else if(ad_data_valid_temp==1'b1 && integral <  $signed('d150000))begin
//            integral<=integral_prev+error;
//        end
//        else begin
//            integral<=integral;
//        end
//    endalways @(posedge clk or negedge rst_n)beginif(!rst_n)begindelta_u_t<=32'd0;end else if(ad_data_valid_temp2==1'b1 && (error >$signed('d100) || error<$signed(-'d100)))begindelta_u_t<=(50*delta_error+5*error)/100;endelse if (ad_data_valid_temp4==1'b1 && (error >$signed('d100) || error<$signed(-'d100)))begindelta_u_t<=32'd0;endendalways @(posedge clk or negedge rst_n)beginif(!rst_n)beginu_t<=32'd7863; //对应0.9Vend else if(ad_data_valid_temp3==1'b1 )beginu_t<=u_t_prev+delta_u_t;endelse beginu_t<=u_t;endendalways @(posedge clk or negedge rst_n)beginif(!rst_n)beginu_t_prev<=32'd0;end else beginu_t_prev<=u_t;endendendmodule

TOP顶层模块

还例化了一个PLL IP核 -生成100m hz的ad_clk

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/11/30 11:10:40
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
module top(//system clocksinput                       sys_clk,input                       rst_n,input[15:0]                 ad7606_data,             //ad7606 datainput                       ad7606_busy,             //ad7606 busyinput                       ad7606_first_data,       //ad7606 first dataoutput[2:0]                 ad7606_os,               //ad7606output                      ad7606_cs,               //ad7606 AD csoutput                      ad7606_rd,               //ad7606 AD data readoutput                      ad7606_reset,            //ad7606 AD resetoutput                      ad7606_convstab,          //ad7606 AD convert startoutput da1_clk,             //AD9767 CH1 clockoutput da1_wrt,             //AD9767 CH1 enableoutput [13:0] da1_data,     //AD9767 CH1 data outputoutput led,output adc_clk, output [3:0]  state,	output da2_clk,             //AD9767 CH2 clockoutput da2_wrt,	            //AD9767 CH2 enableoutput [13:0] da2_data    //AD9767 CH2 data output);
wire [15:0] data_out;      //AD9767 CH2 data output
wire [13:0] da2_data_temp;   //
wire                            ad_data_valid;
wire                            ad_data_valid_temp;
//wire                            adc_clk;      
//wire       [3:0]                state ;
wire                            cal_mode; //wire                            adc_clk;
wire signed[15:0]               ad_ch1;
wire signed[15:0]               ad_ch2;
wire signed[15:0]               ad_ch3;
wire signed[15:0]               ad_ch4;
wire signed[15:0]               ad_ch5;
wire signed[15:0]               ad_ch6;
wire signed[15:0]               ad_ch7;
wire signed[15:0]               ad_ch8;
//wire       [3:0]                state;
wire       [31:0]               ad_v;
wire       [31:0]               da_add;
assign ad_v=da2_data_temp*152;
assign da_add=ad_v/610;
assign da2_data_temp=data_out[13:0];
assign da2_data=da_add+$unsigned('d8192);
assign da1_clk=adc_clk;
assign da1_wrt=adc_clk;
assign da1_data=(cal_mode==1'b0)?14'h2000:14'h2666;assign da2_clk=adc_clk;
assign da2_wrt=adc_clk;
assign led=cal_mode;
adc_pll u_adc_pll_m0(.clk_in1                    (sys_clk                  ),.clk_out1                   (adc_clk                  ),.reset                      (1'b0                     ),.locked                     (                         ));ad_calculate u_ad_calculate(.clk(adc_clk),.rst_n(rst_n),.ad_data_valid(ad_data_valid),.ad_data_valid_temp(ad_data_valid_temp),.ad_ch1(ad_ch1),.ad_ch2(ad_ch2),.ad_ch3(ad_ch3),.cal_mode(cal_mode),.flag_error(),.data_out(data_out));ad7606_if ad7606_if_m0(.clk                   (adc_clk                    ),.rst_n                 (rst_n                      ),.ad_data               (ad7606_data                ), //ad7606 data.ad_busy               (ad7606_busy                ), //ad7606 busy.first_data            (ad7606_first_data          ), //ad7606 first data.ad_os                 (ad7606_os                  ), //ad7606.ad_cs                 (ad7606_cs                  ), //ad7606 AD cs.ad_rd                 (ad7606_rd                  ), //ad7606 AD data read.ad_reset              (ad7606_reset               ), //ad7606 AD reset.ad_convstab           (ad7606_convstab            ), //ad7606 AD convert start.ad_data_valid         (ad_data_valid              ),.ad_data_valid_temp    (ad_data_valid_temp         ),.ad_ch1                (ad_ch1                     ),.ad_ch2                (ad_ch2                     ),.ad_ch3                (ad_ch3                     ),.ad_ch4                (ad_ch4                     ),.ad_ch5                (ad_ch5                     ),.ad_ch6                (ad_ch6                     ),.ad_ch7                (ad_ch7                     ),.ad_ch8                (ad_ch8                     ),.state                 (state                      )
);endmodule

仿真分析

在这里插入图片描述
仿真注意:
AD7606数字量范围与AD9767不同,注意数字量之间要基于基础电压单位进行切换,避免仿真跑飞

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com