名称:心电信号采集AD7606驱动Verilog代码Quartus仿真
软件:Quartus
语言:Verilog
代码功能:基于FPGA的心电信号采集AD7606驱动代码verilog
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
演示视频:
设计文档:
AD7606是ADI(Analog Devices Inc.)公司生产的一款16通道模数转换器,具有高性能和高速采样率的特点。它采用了低功耗的逐次逼近型模数转换技术,并支持SPI和并行两种数据传输模式。在FPGA项目中,AD7606通常用于采集来自外部传感器、信号源或其他外部设备的模拟信号
1. 工程文件
2. 程序文件
3. 程序编译
4. RTL图
5. 管脚分配
6. Signaltap抓取图(AD采样)

7. 部分代码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// 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通道的数据
);
reg [15:0] cnt;
reg [15: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;
assign ad_os=3'b000;
reg[15:0] count;
reg clk1;
always@(posedge clk or negedge rst_n )
if(!rst_n)
begin
count<=0;
clk1<=1'b0;
end
else if(count<=500)
count<=count+1'b1;
else
begin
count<=1'b0;
clk1<=~clk1;
end
//AD 复位电路
always@(posedge clk1)
begin
if(cnt<16'hffff) begin
cnt<=cnt+1;
ad_reset<=1'b1;
end
else
ad_reset<=1'b0;
end
always @(posedge clk1)
begin
if (ad_reset==1'b1) begin
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;
i<=0;
end
else begin
case(state)
IDLE: begin
ad_cs<=1'b1;
ad_rd<=1'b1;
ad_convstab<=1'b1;
if(i==20) begin
i<=0;
state<=AD_CONV;
end
else
i<=i+1'b1;
部分代码展示:
`timescale 1 ns / 100 ps //Use a timescale that is best for simulation. module AD7606 //----------- Ports Declarations ----------------------------------------------- ( //clock and reset signals input fpga_clk_i, //system clock input reset_n_i, //active low reset signal //ad7606 configure pin output [2:0] adc_os_o, // ADC OVERSAMPLING signals output adc_range_o, // ADC RANGE signal output reg adc_reset_o, // ADC RESET signal //state pin input adc_busy_i, // ADC BUSY signal //interface pin output reg adc_convst_o, // ADC CONVST signal output reg adc_cs_n_o, // ADC CS signal output ad7606_sclk,// serial clk input ad7606_sda0,//serial data input A input ad7606_sda1, //serial data input B //test output [7:0]adc_state_o, output SCLK_en_o, output reg [15:0] rx_reg_A_o // Register used for acquiring data // Register used for acquiring data //output reg fifo_wr_en, //output reg fifo_clk ); //ADC states parameter ADC_IDLE_STATE = 8'b00000001; // Default state parameter ADC_START_CONV_STATE = 8'b00000010; // Togle conversion signal parameter ADC_WAIT_BUSY_HIGH_STATE = 8'b00000100; // Wait for the Busy signal to go High parameter ADC_CS_RD_LOW_STATE = 8'b00001000; // Wait for the Busy signal to go Low parameter ADC_WAIT_BUSY_LOW_STATE = 8'b00010000; // Bring CS and RD signals Low parameter ADC_READDATA_STATE = 8'b00100000; // Reads data from the ADC parameter ADC_TRANSFER_DATA_STATE = 8'b01000000; // Sends data to the upper module parameter ADC_WAIT_END_STATE = 8'b10000000; // Waits for the cycle time to end //ADC timing parameter real FPGA_CLOCK_FREQ = 20/2; // FPGA clock frequency [MHz] parameter real ADC_CYCLE_TIME = 40; // minimum time between two ADC conversions (Tcyc) [us] parameter [31:0] ADC_CYCLE_CNT_NO_OS= 390/2-1;//FPGA_CLOCK_FREQ * ADC_CYCLE_TIME-1; parameter [31:0] ADC_CYCLE_CNT_OS2 = 2 * FPGA_CLOCK_FREQ * ADC_CYCLE_TIME-1; parameter [31:0] ADC_CYCLE_CNT_OS4 = 4 * FPGA_CLOCK_FREQ * ADC_CYCLE_TIME-1; parameter [31:0] ADC_CYCLE_CNT_OS8 = 8 * FPGA_CLOCK_FREQ * ADC_CYCLE_TIME-1; parameter [31:0] ADC_CYCLE_CNT_OS16 = 16 * FPGA_CLOCK_FREQ * ADC_CYCLE_TIME-1; parameter [31:0] ADC_CYCLE_CNT_OS32 = 32 * FPGA_CLOCK_FREQ * ADC_CYCLE_TIME-1; parameter [31:0] ADC_CYCLE_CNT_OS64 = 64 * FPGA_CLOCK_FREQ * ADC_CYCLE_TIME-1; reg [7:0] adc_state = ADC_IDLE_STATE; // current state for the ADC control state machine reg [7:0] adc_next_state; // next state for the ADC control state machine reg [15:0] data_i_s =16'hE3; // ADC write data; reg [31:0] cycle_cnt = ADC_CYCLE_CNT_NO_OS; // cycle timescale reg [31:0] tmp_cycle_cnt = ADC_CYCLE_CNT_NO_OS; // cycle timescale reg SCLK_en = 1'b0; // Used to generate SCLK signal reg [63:0] rx_reg_A; // Register used for acquiring data reg [63:0] rx_reg_B; reg [15:0] rx_reg_B_o ; assign adc_range_o = data_i_s[0];//default 1'b1 //assign adc_stdby_o = data_i_s[1];//default 1'b1 assign adc_os_o = data_i_s[4:2];//3'b000 assign adc_state_o = adc_state; assign SCLK_en_o = SCLK_en; reg [ 7:0] sclk_cnt; // Register used for counting the clock signals sent assign ad7606_sclk = SCLK_en ? fpga_clk_i : 1'b0; // clock is idle LOW always @(negedge fpga_clk_i) begin if((reset_n_i == 0) || (ADC_START_CONV_STATE == adc_state)) begin rx_reg_A <= 64'd0; rx_reg_B <= 64'd0; end else if(SCLK_en == 1'b1) begin rx_reg_A <= { rx_reg_A[62:0], ad7606_sda0 }; // V1~V4 rx_reg_B <= { rx_reg_B[62:0], ad7606_sda1 }; // V5~V8 end end //update the ADC timing counters count always @(negedge fpga_clk_i) begin if(reset_n_i == 0) begin tmp_cycle_cnt <= ADC_CYCLE_CNT_NO_OS; adc_convst_o <= 1'b0; end else begin if(adc_state == ADC_IDLE_STATE) begin case(adc_os_o) 3'h0: begin tmp_cycle_cnt <= ADC_CYCLE_CNT_NO_OS; end 3'h1: begin tmp_cycle_cnt <= ADC_CYCLE_CNT_OS2; end 3'h2: begin tmp_cycle_cnt <= ADC_CYCLE_CNT_OS4; end 3'h3: begin tmp_cycle_cnt <= ADC_CYCLE_CNT_OS8; end 3'h4: begin tmp_cycle_cnt <= ADC_CYCLE_CNT_OS16; end 3'h5: begin tmp_cycle_cnt <= ADC_CYCLE_CNT_OS32; end 3'h6: begin tmp_cycle_cnt <= ADC_CYCLE_CNT_OS64; end default: begin tmp_cycle_cnt <= ADC_CYCLE_CNT_NO_OS; end endcase cycle_cnt <= tmp_cycle_cnt; end
点击链接获取代码文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=907
1586