AD7606+Verilog+FPGA+vivado+串口通信+数据解读 并行 全站最全

AD7606+Verilog+FPGA+vivado+串口通信+数据解读 并行 全站最全AD7606vivado 程序串口通信打印八路通道数据 ad7606verilo

大家好,欢迎来到IT知识分享网。

AD7606具有八通道的采集信号,我们可以用它来采集各种模拟信号。我所用的模块如下:

在这里插入图片描述
如上图,右边10个接口,中间CH1~CH8为八路模拟信号输入,其两端为AGND。
左边为单片机或 fpga连接的线。本次用的是并行,所以DB0~DB15作为信号线输出给fpga。
OS0~OS2代码里均设置为0或也可自行接地,即无过采样。CO-A和CO-B连接到fpga的同一个引脚,FR-D可接也可不接,busy,RD/SC(代码对应是ad_rd)。SER接地(相当于并行输出,如果接高电平,相当于串行输出)如下图手册说明。
ser要接低电平才是并行
时序图,程序按看第一(即图2)和第三个(图4)来的。
AD7606+Verilog+FPGA+vivado+串口通信+数据解读 并行 全站最全
在这里插入图片描述






在这里插入图片描述
AD7606_UART代码如下:

`timescale 1ns / 1ps module ad7606_uart( sys_clk, rst_n, ad_data, ad_busy, first_data, ad_os, ad_cs, ad_rd, ad_reset, ad_convstab, uart_tx ); input sys_clk; //50mhz input rst_n; input [15:0] ad_data; //ad7606 采样数据 input ad_busy; //ad7606 忙标志位 input first_data; //ad7606 第一个数据标志位  output [2:0] ad_os; //ad7606 过采样倍率选择 output ad_cs; //ad7606 AD cs output ad_rd; //ad7606 AD data read output ad_reset; //ad7606 AD reset output ad_convstab; //ad7606 AD convert start wire[15:0] ad_ch1 ; //AD第1通道的数据 wire[15:0] ad_ch2 ; //AD第2通道的数据 wire[15:0] ad_ch3 ; //AD第3通道的数据 wire[15:0] ad_ch4 ; //AD第4通道的数据 wire[15:0] ad_ch5 ; //AD第5通道的数据 wire[15:0] ad_ch6 ; //AD第6通道的数据 wire[15:0] ad_ch7 ; //AD第7通道的数据 wire[15:0] ad_ch8 ; //AD第8通道的数据 */ wire[15:0]data1 ; wire[15:0]data2 ; wire[15:0]data3 ; wire[15:0]data4 ; wire[15:0]data5 ; wire[15:0]data6 ; wire[15:0]data7 ; wire[15:0]data8 ; output uart_tx; ad7606 ad7606( . clk(sys_clk), //50mhz . rst_n(rst_n), . ad_data(ad_data), //ad7606 采样数据 . ad_busy(ad_busy), //ad7606 忙标志位 . first_data( first_data), //ad7606 第一个数据标志位  . ad_os(ad_os), //ad7606 过采样倍率选择 . ad_cs(ad_cs), //ad7606 AD cs . ad_rd(ad_rd), //ad7606 AD data read . ad_reset(ad_reset), //ad7606 AD reset . ad_convstab(ad_convstab), //ad7606 AD convert start .ad_ch1(ad_ch1), //AD第1通道的数据 .ad_ch2(ad_ch2), //AD第2通道的数据 .ad_ch3(ad_ch3), //AD第3通道的数据 .ad_ch4(ad_ch4), //AD第4通道的数据 .ad_ch5(ad_ch5), //AD第5通道的数据 .ad_ch6(ad_ch6), //AD第6通道的数据 .ad_ch7(ad_ch7), //AD第7通道的数据 .ad_ch8(ad_ch8) //AD第8通道的数据  //output reg [3:0] cnt ); uart_test uart_test( .sys_clk(sys_clk) , //system clock 50Mhz on board .rst_n(rst_n) , //reset ,low active .data1(ad_ch1) , .data2(ad_ch2) , .data3(ad_ch3) , .data4(ad_ch4) , .data5(ad_ch5) , .data6(ad_ch6) , .data7(ad_ch7) , .data8(ad_ch8) , .uart_tx(uart_tx) ); endmodule 

底层ad7606代码如下:

`timescale 1ns / 1ns // // Module Name: ad7606  // module ad7606( input clk, //50mhz input rst_n, input [15:0] ad_data, //ad7606 采样数据 input ad_busy, //ad7606 忙标志位 input first_data, //ad7606 第一个数据标志位  output [2:0] ad_os, //ad7606 过采样倍率选择 output reg ad_cs, //ad7606 AD cs output reg ad_rd, //ad7606 AD data read output reg ad_reset, //ad7606 AD reset output reg ad_convstab, //ad7606 AD convert start output reg [15:0] ad_ch1, //AD第1通道的数据 output reg [15:0] ad_ch2, //AD第2通道的数据 output reg [15:0] ad_ch3, //AD第3通道的数据 output reg [15:0] ad_ch4, //AD第4通道的数据 output reg [15:0] ad_ch5, //AD第5通道的数据 output reg [15:0] ad_ch6, //AD第6通道的数据 output reg [15:0] ad_ch7, //AD第7通道的数据 output reg [15:0] ad_ch8 //AD第8通道的数据  //output reg [3:0] cnt ); reg [3:0] state; reg [7:0] cnt = 0 ; reg [15:0] cnt50us = 0; reg [5:0] i; //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; //parameter display=4'd13; assign ad_os=3'b000; //无过采样 //ad复位 always@(posedge clk) begin if(cnt<8'hff) begin cnt<=cnt+1; ad_reset<=1'b1; end else ad_reset<=1'b0; //计数器达到ff后停止,ad_reset恒为零  end //使用定时器来设置采样频率 always @(posedge clk or negedge rst_n) //每50us读取一次数据,ad的采样率为20K begin if(rst_n == 0) cnt50us <= 0; else begin if(cnt50us < 16'd2499) begin cnt50us <= cnt50us + 1; end else cnt50us <= 0; end end always @(posedge clk) begin if (ad_reset==1'b1) begin //初始化ad state<=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; //8通道同步采样 i<=0; end else begin case(state) //need time:(20+2+5+1+3*8+1)*20ns=1060ns, fmax=1/1060ns=1MHZ IDLE: begin ad_cs<=1'b1; ad_rd<=1'b1; ad_convstab<=1'b1; if(i==20) begin //延时20个时钟后开始转换 i<=0; state<=AD_CONV; end else i<=i+1'b1; end AD_CONV: begin if(i==2) begin //等待2个lock,convstab的下降沿最少为25ns,故至少需要两个时钟 i<=0; state<=Wait_1; ad_convstab<=1'b1; end else begin i<=i+1'b1; ad_convstab<=1'b0; //启动AD转换 end end Wait_1: begin if(i==5) begin //等待5个clock, 等待busy信号为高(tconv) i<=0; state<=Wait_busy; end else i<=i+1'b1; end Wait_busy: begin if(ad_busy==1'b0) begin //等待busy为低电平 即转换之后读取模式 i<=0; state<=READ_CH1; end end READ_CH1: begin ad_cs<=1'b0; //cs信号有效 直到读取8通道结束 if(i==3) begin // 低电平持续3个时钟,完成通道1的读入 ad_rd<=1'b1; i<=0; ad_ch1<=ad_data; //读CH1 state<=READ_CH2; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH2: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch2<=ad_data; //读CH2 state<=READ_CH3; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH3: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch3<=ad_data; //读CH3 state<=READ_CH4; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH4: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch4<=ad_data; //读CH4 state<=READ_CH5; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH5: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch5<=ad_data; //读CH5 state<=READ_CH6; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH6: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch6<=ad_data; //读CH6 state<=READ_CH7; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH7: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch7<=ad_data; //读CH7 state<=READ_CH8; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH8: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch8<=ad_data; //读CH8 state<=READ_DONE; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_DONE:begin //完成读,回到idle状态 ad_rd<=1'b1; ad_cs<=1'b1; if(cnt50us == 16'd2499) //不加此条件,则ad完成一次读取需1280ns,采样频率781.25K,但需注意ad每通道的追高采样只能为200K state<=IDLE; else state<=READ_DONE; end default: state<=IDLE; endcase end end endmodule 

uart_test代码如下:

 module uart_test( input sys_clk, //system clock 50Mhz on board input rst_n, //reset ,low active input [15:0] data1, input [15:0] data2, input [15:0] data3, input [15:0] data4, input [15:0] data5, input [15:0] data6, input [15:0] data7, input [15:0] data8, output uart_tx ); parameter CLK_FRE = 50;//Mhz localparam IDLE = 0; localparam SEND = 1; //send HELLO ALINX\r\n localparam WAIT = 2; //wait 1 second and send uart received data reg[7:0] tx_data; reg[7:0] tx_str; reg tx_data_valid; wire tx_data_ready; reg[7:0] tx_cnt; reg[31:0] wait_cnt; reg[3:0] state; always@(posedge sys_clk or negedge rst_n) begin if(rst_n == 1'b0) begin wait_cnt <= 32'd0; tx_data <= 8'd0; state <= IDLE; tx_cnt <= 8'd0; tx_data_valid <= 1'b0; end else case(state) IDLE: state <= SEND; SEND: begin wait_cnt <= 32'd0; tx_data <= tx_str; if(tx_data_valid == 1'b1 && tx_data_ready == 1'b1 && tx_cnt < 8'd23)//Send 12 bytes data begin tx_cnt <= tx_cnt + 8'd1; //Send data counter end else if(tx_data_valid && tx_data_ready)//last byte sent is complete begin tx_cnt <= 8'd0; tx_data_valid <= 1'b0; state <= WAIT; end else if(~tx_data_valid) begin tx_data_valid <= 1'b1; end end WAIT: begin wait_cnt <= wait_cnt + 32'd1; if(tx_data_valid && tx_data_ready) begin tx_data_valid <= 1'b0; end else if(wait_cnt >= CLK_FRE * ) // wait for 1 second state <= SEND; end default: state <= IDLE; endcase end //combinational logic //Send "HELLO ALINX\r\n" always@(*) begin case(tx_cnt) 8'd0 : tx_str <= "C1"; 8'd1 : tx_str <= data1[15:8]; 8'd2 : tx_str <= data1[7:0]; 8'd3: tx_str <= "C2"; 8'd4 : tx_str <= data2[15:8]; 8'd5 : tx_str <= data2[7:0]; 8'd6: tx_str <= "C3"; 8'd7 : tx_str <= data3[15:8]; 8'd8 : tx_str <= data3[7:0]; 8'd9: tx_str <= "C4"; 8'd10 : tx_str <= data4[15:8]; 8'd11 : tx_str <= data4[7:0]; 8'd12: tx_str <= "C5"; 8'd13 : tx_str <= data5[15:8]; 8'd14 : tx_str <= data5[7:0]; 8'd15: tx_str <= "C6"; 8'd16 : tx_str <= data6[15:8]; 8'd17 : tx_str <= data6[7:0]; 8'd18: tx_str <= "C7"; 8'd19 : tx_str <= data7[15:8]; 8'd20 : tx_str <= data7[7:0]; 8'd21: tx_str <= "C8"; 8'd22 : tx_str <= data8[15:8]; 8'd23 : tx_str <= data8[7:0]; default:tx_str <= 8'd0; endcase end uart_tx# ( .CLK_FRE(CLK_FRE), .BAUD_RATE() ) uart_tx_inst ( .clk (sys_clk ), .rst_n (rst_n ), .tx_data (tx_data ), .tx_data_valid (tx_data_valid ), .tx_data_ready (tx_data_ready ), .tx_pin (uart_tx ) ); endmodule 

uart_test同样包含一个子模块,如下:

 module uart_tx #( parameter CLK_FRE = 50, //clock frequency(Mhz) parameter BAUD_RATE =  //serial baud rate ) ( input clk, //clock input input rst_n, //asynchronous reset input, low active  input[7:0] tx_data, //data to send input tx_data_valid, //data to be sent is valid output reg tx_data_ready, //send ready output tx_pin //serial data output ); //calculates the clock cycle for baud rate  localparam CYCLE = CLK_FRE *  / BAUD_RATE; //state machine code localparam S_IDLE = 1; localparam S_START = 2;//start bit localparam S_SEND_BYTE = 3;//data bits localparam S_STOP = 4;//stop bit reg[2:0] state; reg[2:0] next_state; reg[15:0] cycle_cnt; //baud counter reg[2:0] bit_cnt;//bit counter reg[7:0] tx_data_latch; //latch data to send reg tx_reg; //serial data output assign tx_pin = tx_reg; always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) state <= S_IDLE; else state <= next_state; end always@(*) begin case(state) S_IDLE: if(tx_data_valid == 1'b1) next_state <= S_START; else next_state <= S_IDLE; S_START: if(cycle_cnt == CYCLE - 1) next_state <= S_SEND_BYTE; else next_state <= S_START; S_SEND_BYTE: if(cycle_cnt == CYCLE - 1 && bit_cnt == 3'd7) next_state <= S_STOP; else next_state <= S_SEND_BYTE; S_STOP: if(cycle_cnt == CYCLE - 1) next_state <= S_IDLE; else next_state <= S_STOP; default: next_state <= S_IDLE; endcase end always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) begin tx_data_ready <= 1'b0; end else if(state == S_IDLE) if(tx_data_valid == 1'b1) tx_data_ready <= 1'b0; else tx_data_ready <= 1'b1; else if(state == S_STOP && cycle_cnt == CYCLE - 1) tx_data_ready <= 1'b1; end always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) begin tx_data_latch <= 8'd0; end else if(state == S_IDLE && tx_data_valid == 1'b1) tx_data_latch <= tx_data; end always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) begin bit_cnt <= 3'd0; end else if(state == S_SEND_BYTE) if(cycle_cnt == CYCLE - 1) bit_cnt <= bit_cnt + 3'd1; else bit_cnt <= bit_cnt; else bit_cnt <= 3'd0; end always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) cycle_cnt <= 16'd0; else if((state == S_SEND_BYTE && cycle_cnt == CYCLE - 1) || next_state != state) cycle_cnt <= 16'd0; else cycle_cnt <= cycle_cnt + 16'd1; end always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tx_reg <= 1'b1; else case(state) S_IDLE,S_STOP: tx_reg <= 1'b1; S_START: tx_reg <= 1'b0; S_SEND_BYTE: tx_reg <= tx_data_latch[bit_cnt]; default: tx_reg <= 1'b1; endcase end endmodule 
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[15]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[14]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[13]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[12]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[11]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[10]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[9]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[8]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[7]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[6]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[5]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[4]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[3]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[2]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[1]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_data[0]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_os[2]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_os[1]}] set_property IOSTANDARD LVCMOS33 [get_ports { 
   ad_os[0]}] set_property IOSTANDARD LVCMOS33 [get_ports ad_busy] set_property IOSTANDARD LVCMOS33 [get_ports ad_cs] set_property IOSTANDARD LVCMOS33 [get_ports ad_convstab] set_property IOSTANDARD LVCMOS33 [get_ports ad_rd] set_property IOSTANDARD LVCMOS33 [get_ports ad_reset] set_property IOSTANDARD LVCMOS33 [get_ports clk] set_property IOSTANDARD LVCMOS33 [get_ports first_data] set_property IOSTANDARD LVCMOS33 [get_ports rst_n] set_property IOSTANDARD LVCMOS33 [get_ports sys_clk] set_property IOSTANDARD LVCMOS33 [get_ports uart_tx] set_property PACKAGE_PIN N17 [get_ports { 
   ad_data[15]}] set_property PACKAGE_PIN P18 [get_ports { 
   ad_data[14]}] set_property PACKAGE_PIN R16 [get_ports { 
   ad_data[13]}] set_property PACKAGE_PIN R17 [get_ports { 
   ad_data[12]}] set_property PACKAGE_PIN T16 [get_ports { 
   ad_data[11]}] set_property PACKAGE_PIN U17 [get_ports { 
   ad_data[10]}] set_property PACKAGE_PIN W18 [get_ports { 
   ad_data[9]}] set_property PACKAGE_PIN W19 [get_ports { 
   ad_data[8]}] set_property PACKAGE_PIN Y18 [get_ports { 
   ad_data[7]}] set_property PACKAGE_PIN Y19 [get_ports { 
   ad_data[6]}] set_property PACKAGE_PIN Y16 [get_ports { 
   ad_data[5]}] set_property PACKAGE_PIN Y17 [get_ports { 
   ad_data[4]}] set_property PACKAGE_PIN V17 [get_ports { 
   ad_data[3]}] set_property PACKAGE_PIN V18 [get_ports { 
   ad_data[2]}] set_property PACKAGE_PIN W14 [get_ports { 
   ad_data[1]}] set_property PACKAGE_PIN Y14 [get_ports { 
   ad_data[0]}] set_property PACKAGE_PIN V16 [get_ports { 
   ad_os[2]}] set_property PACKAGE_PIN W16 [get_ports { 
   ad_os[1]}] set_property PACKAGE_PIN T17 [get_ports { 
   ad_os[0]}] set_property PACKAGE_PIN R18 [get_ports ad_busy] set_property PACKAGE_PIN V12 [get_ports ad_convstab] set_property PACKAGE_PIN W13 [get_ports ad_cs] set_property PACKAGE_PIN T14 [get_ports ad_rd] set_property PACKAGE_PIN T15 [get_ports ad_reset] set_property PACKAGE_PIN T11 [get_ports clk] set_property PACKAGE_PIN T10 [get_ports first_data] set_property PACKAGE_PIN P16 [get_ports rst_n] set_property PACKAGE_PIN N18 [get_ports sys_clk] set_property PACKAGE_PIN P14 [get_ports uart_tx] 

在这里插入图片描述
看其他CH2~CH8,取其中一个CH2 的数据1A 7B。同样接着计算,
在这里插入图片描述
在这里插入图片描述
结果为2V,与通道号悬空时候实测电压一致。至此程序的编写没问题。



免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/119259.html

(0)
上一篇 2025-11-06 19:45
下一篇 2025-11-06 20:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信