AD7606时序分析与verilog HDL实现

AD7606是16位,8/6/4通道同步采样模数转换芯片,各器件内置模拟输入钳位保护,二阶抗混叠滤波器,跟踪保持放大器,16位电荷再分配逐次逼近式模数转换器。
在这里插入图片描述
其中:
CONVST:启动转换信号
busy:转换完成信号
cs:片选信号
reset:复位信号
读取AD数据时序如下:
在这里插入图片描述
AD采样流程如下:
1、拉低CONVST信号启动转换
2、读取busy信号,当busy信号为低时,说明转换完成,可以读取采样数据,然后触发中断去读取数据
3、读取数据时,先使能CS信号,然后变换RD信号读取数据(注意:每读取一个通道的数据,RD使能到禁止使能一次,AD7606CS保持使能,不能喝RD同步变化,这点在有的AD上面有所不同如MAX125,本人在更换AD芯片时没有注意这点时序变化,导致查了两天时间)
4、8个通道数据读取完成后禁止使能CS,等待下次读取。
当AD独享数据总线时刻采用RD和CS并联的结构,如下图:
在这里插入图片描述
其时序如下图所示:
在这里插入图片描述

多句嘴,这个时序如果用FPGA实现的话,效率会很高,更能满足采样率要求高的设计。

verilog HDL设计实现如下所示:

//*******************************************************//
//               采样模块模块    6片7606AD                 //
//*******************************************************//
module AD7606_6(
		input rst_n,/*系统复位*/
		input clk_50m,/*时钟*/
		input [31:0]sampleCnt,/*采样时钟计数*/
		input [7:0]inS_data,/*AD数据总线*/
		input [5:0]buzy,/*AD忙信号*/
		output reg rst,/*AD复位总信号*/
		output reg convst,/*AD数据装换总信号*/
		output reg [5:0]cs_n,/*AD片选信号*/
		output reg rd_n,/*AD读信号*/
		output reg IsDataReady, /*一点数据完成读取*/
		output reg [7:0]DataOut/*AD数据*/
		);
		
parameter   [13:0]    AD_RESET_P    = 14'b00_0000_0000_0000;
parameter   [13:0]    AD_RESET_N   	= 14'b00_0000_0000_0001;
parameter   [13:0]    AD_START_SP		= 14'b00_0000_0000_0010;
parameter   [13:0]    AD_CONVST_P  	= 14'b00_0000_0000_0100;
parameter   [13:0]    AD_BUSY_P   	= 14'b00_0000_0000_1000;
parameter   [13:0]    AD_BUSY_N   	= 14'b00_0000_0001_0000;
parameter   [13:0]    AD_CS_N      	= 14'b00_0000_0010_0000; 
parameter   [13:0]    AD_RD_N      	= 14'b00_0000_1000_0000; 
parameter   [13:0]    AD_GET_DATA  	= 14'b00_0001_0000_0000; 
parameter   [13:0]    AD_RD_P 			= 14'b00_0100_0000_0000;
parameter   [13:0]    AD_RD_P1			= 14'b00_1000_0000_0000;
parameter   [13:0]    AD_CS_P 			= 14'b01_0000_0000_0000;
parameter   [13:0]    AD_CS_P1 			= 14'b10_0000_0000_0000;

//当前ad采样序号
reg[3:0] ad_index;//当前AD序号
reg[4:0] ad_data_index;//当前AD数据序号
//
		
parameter AD_NUM = 6;		//

reg clk_ad;
reg ad_start_sp_neg_tri;
reg[31:0] clk_ad_cnt;

always @(posedge clk_50m or negedge rst_n)
begin
	if(!rst_n)begin
		clk_ad <= 1'b0;
		clk_ad_cnt <= 32'd0;
	end
	else if(clk_ad_cnt>=sampleCnt)begin//
		clk_ad <= ~clk_ad;
		clk_ad_cnt <= 32'd0;
	end
	else begin
		clk_ad_cnt <= clk_ad_cnt +1'b1;
	end

end

/*AD采样状态转换*/
reg[13:0] current_state;//当前状态
reg ad_count_ena;//计数器使能
reg[23:0] ad_count;//计数器
//
/*AD采样状态转换*/
always @(posedge clk_50m or negedge rst_n)
begin
	if(!rst_n)begin
		current_state <= AD_RESET_P;
		ad_count_ena <= 1'b0;
		ad_count <= 24'd0;
		rst <= 1'b0;
		convst <= 1'b0;
		rd_n <= 1'b1;
		cs_n <= {AD_NUM{1'b1}};
		IsDataReady <= 1'b0;
	end
	else if(ad_count_ena) begin
	if(ad_count<=24'd1)
			ad_count_ena <= 1'b0;
		else
			ad_count <= ad_count-1'b1;
	end
	else begin
		case(current_state)
			AD_RESET_P:begin
				current_state <= AD_RESET_N;
				ad_count_ena <= 1'b1;
				ad_count <= 24'd3;
				
				rst <= 1'b1;
				convst <= 1'b0;
				rd_n <= 1'b1;
				cs_n <= {AD_NUM{1'b1}};
			end
			AD_RESET_N:begin
				current_state <= AD_START_SP;
				ad_count_ena <= 1'b1;
				ad_count <= 24'd2;
				
				rst <= 1'b0;
				convst <= 1'b0;
				rd_n <= 1'b1;
				cs_n <= {AD_NUM{1'b1}};
			end
			AD_START_SP:begin
				if(ad_start_sp_neg_tri!=clk_ad)begin
					current_state <= AD_CONVST_P;
					ad_count_ena <= 1'b1;
					ad_count <= 24'd3;//等待buzy信号
					ad_start_sp_neg_tri<=clk_ad;
					
					convst <= 1'b1;//AD转换开始
					rd_n <= 1'b1;
					cs_n <= {AD_NUM{1'b1}};
				end
				else begin
					current_state <= AD_START_SP;//等待。。。
					ad_count_ena <= 1'b0;
					ad_count <= 24'd0;
					
					convst <= 1'b0;
					rd_n <= 1'b1;
					cs_n <= {AD_NUM{1'b1}};
				end
			end
			AD_CONVST_P:begin
				if(buzy == {AD_NUM{1'd1}})begin
					current_state <= AD_BUSY_P;
					ad_count_ena <= 1'b1;
					ad_count <= 24'd230;
				end
				else begin
					current_state <= AD_RESET_P;
					ad_count_ena <= 1'b1;
					ad_count <= 24'd6;
					rst <= 1'b1;
				end
				
				rd_n <= 1'b1;
				cs_n <= {AD_NUM{1'b1}};
			end
			AD_BUSY_P:begin
				
				
				if(buzy == {AD_NUM{1'd0}})begin
					current_state <= AD_BUSY_N;
					ad_count_ena <= 1'b1;
					ad_count <= 24'd1;
					
					ad_index <=4'd0;//AD序号清零
				end
				else begin
					current_state <= AD_BUSY_P;
					ad_count_ena <= 1'b1;
					ad_count <= 24'd6;
				end
			end
			AD_BUSY_N:begin
				current_state <= AD_CS_N;
				ad_count_ena <= 1'b0;
				ad_count <= 24'd0;
			end
			AD_CS_N:begin
				current_state <= AD_RD_N;
				ad_count_ena <= 1'b1;
				ad_count <= 24'd2;
				
				ad_data_index <=5'd0;
				cs_n <= {AD_NUM{1'b1}} & (~({6'b000001}<<ad_index));
			end
			AD_RD_N:begin
				current_state <= AD_GET_DATA;
				ad_count_ena <= 1'b1;
				ad_count <= 24'd2;
				
				rd_n <= 1'b0;//AD读使能	
			end
			AD_GET_DATA:begin
				current_state <= AD_RD_P;
				ad_count_ena <= 1'b0;
				ad_count <= 24'd0;
				DataOut <= inS_data;//取AD数据	
				IsDataReady <= 1'b1;
			end
			AD_RD_P:begin
				current_state <= AD_RD_P1;
				ad_count_ena <= 1'b1;
				ad_count <= 24'd2;
				
				IsDataReady <= 1'b0;
				ad_data_index <= ad_data_index +1'b1;
				rd_n <= 1'b1;//AD读禁能
			end
			AD_RD_P1:begin
				if(ad_data_index==5'd16)begin
					current_state <= AD_CS_P;	
					ad_count_ena <= 1'b1;
					ad_count <= 24'd1;				
				end
				else begin
					current_state <= AD_RD_N;
					ad_count_ena <= 1'b0;
					ad_count <= 24'd0;
				end
			end
			AD_CS_P:begin
				current_state <= AD_CS_P1;
				ad_count_ena <= 1'b1;
				ad_count <= 24'd2;
				
				ad_index <= ad_index +1'b1;
				cs_n <= {AD_NUM{1'b1}};//片选结束
			end
			AD_CS_P1:begin
				if(ad_index==AD_NUM)begin
					current_state <= AD_START_SP;
					convst <= 1'b0;//AD转换停止
				end
				else begin
					current_state <= AD_CS_N;
				end
			end
		endcase
	end
end

endmodule
  • 14
    点赞
  • 115
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
下面是一个基于 Xilinx FPGA 的 Vivado 开发环境,通过 Verilog HDL 实现对 AD7985 时序逻辑控制的示例代码: ```verilog module ad7985_controller( input wire clk, // 系统时钟 input wire rst, // 系统复位 output wire cs_n, // 片选信号 output wire sclk, // 时钟信号 output wire cnvst, // 启动转换信号 input wire [15:0] din, // 数据输入 output reg [15:0] dout // 数据输出 ); reg [1:0] state; // 状态寄存器 reg [15:0] data; // 数据寄存器 reg [3:0] cnt; // 计数器 parameter IDLE = 2'b00; // 空闲状态 parameter ACQUIRE = 2'b01; // 采集状态 parameter CONVERT = 2'b10; // 转换状态 assign cs_n = state == IDLE ? 1'b1 : 1'b0; // 片选信号 assign sclk = state == IDLE ? 1'b0 : 1'b1; // 时钟信号 always @(posedge clk) begin if (rst) begin state <= IDLE; cnvst <= 1'b0; dout <= 16'b0; data <= 16'b0; cnt <= 4'b0; end else begin case (state) IDLE: begin dout <= data; if (cnvst) begin state <= ACQUIRE; cnt <= 4'b0; sclk <= 1'b0; end end ACQUIRE: begin if (cnt == 4'b0000) begin cnvst <= 1'b1; sclk <= 1'b1; cnt <= cnt + 1; end else if (cnt == 4'b0001) begin cnvst <= 1'b0; sclk <= 1'b0; cnt <= cnt + 1; end else if (cnt == 4'b0010) begin cnvst <= 1'b1; sclk <= 1'b1; cnt <= cnt + 1; end else if (cnt == 4'b0011) begin cnvst <= 1'b0; sclk <= 1'b0; cnt <= cnt + 1; end else if (cnt == 4'b0100) begin cnvst <= 1'b1; sclk <= 1'b1; cnt <= cnt + 1; end else if (cnt == 4'b0101) begin cnvst <= 1'b0; sclk <= 1'b0; cnt <= cnt + 1; end else if (cnt == 4'b0110) begin cnvst <= 1'b1; sclk <= 1'b1; cnt <= cnt + 1; end else if (cnt == 4'b0111) begin cnvst <= 1'b0; sclk <= 1'b0; cnt <= cnt + 1; end else if (cnt == 4'b1000) begin cnvst <= 1'b1; sclk <= 1'b1; cnt <= cnt + 1; end else if (cnt == 4'b1001) begin cnvst <= 1'b0; sclk <= 1'b0; cnt <= cnt + 1; end else begin state <= CONVERT; cnt <= 4'b0; sclk <= 1'b0; end end CONVERT: begin cnvst <= 1'b0; sclk <= 1'b0; state <= IDLE; data <= din; end endcase end end endmodule ``` 上述代码中,我们定义了一个 AD7985 时序逻辑控制模块,包括系统时钟 clk、系统复位 rst、片选信号 cs_n、时钟信号 sclk、启动转换信号 cnvst、数据输入 din 和数据输出 dout。同时,我们还定义了一个状态寄存器 state、一个数据寄存器 data 和一个计数器 cnt。 控制模块的状态分为三种:IDLE(空闲状态)、ACQUIRE(采集状态)和CONVERT(转换状态)。在空闲状态下,片选信号 cs_n 为高电平,时钟信号 sclk 为低电平。当启动转换信号 cnvst 为高电平时,控制模块进入采集状态,此时片选信号 cs_n 为低电平,时钟信号 sclk 为高电平。在采集状态下,控制模块按照 AD7985 的时序要求控制启动转换信号 cnvst 和时钟信号 sclk 的变化,以实现对 AD7985 的采集控制。在转换状态下,控制模块将数据输入 din 存入数据寄存器,并将状态寄存器置为 IDLE,同时输出数据输出 dout。 控制模块的实现采用了 Verilog HDL 语言,通过状态机和计数器的方式实现了对 AD7985 时序逻辑的精确控制。在实际应用中,我们需要根据 AD7985 的具体规格和接口要求进行修改,并添加适当的时序控制逻辑,以实现对 AD7985 的精确控制和数据采集。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值