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
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页