欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

FPGA之ADS8344驱动程序

程序员文章站 2022-07-03 14:02:59
...

FPGA之ADS8344驱动程序*

前言

在学习完小梅老师的《线性序列机与TLV1544驱动设计》后,本人受到小梅老师“用线性序列机”设计AD/DA驱动程序的启发后开始渴望掌握这种方法,于是开始拿“ADS8344”练手。

ADS8344简介

   ADS8344是采用20引脚QSDP封装或SSOP封装的芯片,是一个高速、低功耗、16位逐次逼近型ADC。(咱就做个简单的简介,更详细内容可以去参考ASD8344的数据手册)

FPGA之ADS8344驱动程序

模块代码分析

端口定义代码

module ADS8344(
      Clk,
		Rst_n,
		
		Do_Conv,     //开始转换使能信号
		ADS_CHSEL,   //模拟通道选择、模拟输入方式选择和功率管理选择信号
		ADS_DONE,    //转换完成信号
		
		ADS_DATA,
		DATA_Valid,  //数据有效信号,转换完成的有效数据给ADS_DATA
		
		ADS8344_CS,
		ADS8344_DCLK,
		ADS8344_DIN,
		ADS8344_BUSY,
		ADS8344_DOUT
		);

端口类型定义

input Clk;
		input Rst_n;
		input Do_Conv;
		
		input [7:0]ADS_CHSEL;
		
		output reg [15:0]ADS_DATA;
		output reg ADS_DONE;
		output reg DATA_Valid;
		
		output reg ADS8344_CS;
		output reg ADS8344_DCLK;
		output reg ADS8344_DIN;
		input   ADS8344_BUSY;
		input   ADS8344_DOUT;

定义两个寄存器,ADS_RDATA用于寄存ADS_DOUT转换输出的数据,LSM_CNT为9位的序列计数器

	reg [15:0]ADS_RDATA; //ADS8344_DOUT输出的数据先寄存在ADS_RDATA,当DATA_Valid为1时数据给ADS_DATA
	reg [8:0]LSM_CNT;   //序列计数器

复位

aaa@qq.com(posedge Clk or negedge Rst_n )
		   if(!Rst_n) 
			  LSM_CNT<=9'd0;
			else if((LSM_CNT<301)&&Do_Conv)   
			  LSM_CNT<=LSM_CNT+1'b1;
			else if(LSM_CNT==301)
			  LSM_CNT<=9'd0;
aaa@qq.com(posedge Clk or negedge Rst_n )
		    if(!Rst_n)
			   begin 
				  ADS8344_CS<=1'b1;
		        ADS8344_DCLK<=1'b0;
		        ADS8344_DIN<=1'b0;
				  ADS_DONE<=1'b0;
				  ADS_RDATA[15:0]<=16'd0;
				  DATA_Valid<=1'b0;
				  ADS_DATA<=16'd0;
				end 

当复位为1时(Rst_n==1’b1),开始执行程序,判断序列机LSM_CNT状态,根据其状态执行其相应状态下的语句。LSM_CNT计数值为0时,所有状态为复位时的状态,除复位为1外。

 case(LSM_CNT)
					    0:
						   begin 
				        ADS8344_CS<=1'b1;
		                ADS8344_DCLK<=1'b0;
		                ADS8344_DIN<=1'b0;
				        ADS_DONE<=1'b0;
				        ADS_RDATA[15:0]<=16'd0;
				        DATA_Valid<=1'b0;
				        ADS_DATA<=16'd0;
				         end 

片选信号为0,芯片开始工作

                         1:
						    begin 
							  ADS8344_CS<=1'b0;
							 end

DIN开始接受模拟通道选择、模拟输入方式选择和功率管理选择信号。

                         7:
						    begin
							  ADS8344_DCLK<=1'b1;
							  ADS8344_DIN<=ADS_CHSEL[7];
							 end 
							 
						 13:
						    begin 
							  ADS8344_DCLK<=1'b0;
							 end 
							 
						 19:
						    begin
							  ADS8344_DCLK<=1'b1;
							  ADS8344_DIN<=ADS_CHSEL[6];
							 end 
							 
						 25:
						    begin 
							  ADS8344_DCLK<=1'b0;
							 end 
							 
						 31:
						    begin
							  ADS8344_DCLK<=1'b1;
							  ADS8344_DIN<=ADS_CHSEL[5];
							 end 
							 
						 37:
						    begin 
							  ADS8344_DCLK<=1'b0;
							 end 
							 
						 43:
						    begin
							  ADS8344_DCLK<=1'b1;
							  ADS8344_DIN<=ADS_CHSEL[4];
							 end 
							 
						 49:
						    begin 
							  ADS8344_DCLK<=1'b0;
							 end 
							 
						 55:
						    begin
							  ADS8344_DCLK<=1'b1;
							  ADS8344_DIN<=ADS_CHSEL[3];
							 end 
							 
						 61:
						    begin 
							  ADS8344_DCLK<=1'b0;
							 end 
							 
						 67:
						    begin
							  ADS8344_DCLK<=1'b1;
							  ADS8344_DIN<=ADS_CHSEL[2];
							 end 
							 
						 73:
						    begin 
							  ADS8344_DCLK<=1'b0;
							 end 
							 
						 79:
						    begin
							  ADS8344_DCLK<=1'b1;
							  ADS8344_DIN<=ADS_CHSEL[1];
							 end 
							 
						 85:
						    begin 
							  ADS8344_DCLK<=1'b0;
							 end 
							 
						 91:
						    begin
							  ADS8344_DCLK<=1'b1;
							  ADS8344_DIN<=ADS_CHSEL[0];
							 end 
							 
						 97:
						    begin 
							  ADS8344_DCLK<=1'b0;
							 end 

数据采集完成,芯片开始转换,转换时间为一个时钟周期,此时BUSY被拉高。

                         97:
						    begin 
							  ADS8344_DCLK<=1'b0;
							 end 
							 
						 103:
						     begin
							  ADS8344_DCLK<=1'b1;
							  end 
							  
						 109:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  

当BUSY下降变成低电平时,ADS_DOUT开始输出转换完成的数据

                        127:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[14]<=ADS8344_DOUT;
							  end 
							  
						 133:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 139:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[13]<=ADS8344_DOUT;
							  end 
							  
						 145:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 151:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[12]<=ADS8344_DOUT;
							  end 
							  
						 157:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 163:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[11]<=ADS8344_DOUT;
							  end 
							  
						 169:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 175:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[10]<=ADS8344_DOUT;
							  end 
							  
						 181:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 187:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[9]<=ADS8344_DOUT;
							  end 
							  
						 193:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 199:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[8]<=ADS8344_DOUT;
							  end 
							  
						 205:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 211:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[7]<=ADS8344_DOUT;
							  end 
							  
						 217:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 223:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[6]<=ADS8344_DOUT;
							  end 
							  
						 229:
						     begin 
							  ADS8344_DCLK<=1'b0;
							 end 
							 
						 235:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[5]<=ADS8344_DOUT;
							  end 
							  
						 241:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 247:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[4]<=ADS8344_DOUT;
							  end 
							  
						 253:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 259:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[3]<=ADS8344_DOUT;
							  end 
							  
						 265:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 271:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[2]<=ADS8344_DOUT;
							  end 
							  
						 277:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  
						 283:
						     begin
							  ADS8344_DCLK<=1'b1;
							  ADS_RDATA[1]<=ADS8344_DOUT;
							  end 
							  
						 289:
						     begin 
							  ADS8344_DCLK<=1'b0;
							  end 
							  

当最后一个转换数据输出时,输出数据有效信号DATA_Valid为1,ADS_RDATA寄存器的数据传输给数据输出端ADS_DATA。

                        295:
						     begin
							  ADS8344_DCLK<=1'b1;
							  if(! ADS8344_BUSY)
							  DATA_Valid<=1'b1;   //转换数据有效,开始输出
							  else
							  DATA_Valid<=1'b0;    
							  ADS_DATA<={ADS_RDATA[15:1],ADS8344_DOUT};
							  end 

转换完成,片选拉高,转换完成信号拉高

                      301:
						    begin 
							  ADS8344_DCLK<=1'b0;
							  ADS8344_CS<=1'b1;
							  ADS_DONE<=1'b1;
							 end 

计数器的其他情况下数据输出有效信号无效(为0)。

 default: DATA_Valid<=1'b0;

仿真代码

设置一个20ns的时钟

        initial Clk=1'b1;
		always #(`clk_period/2) Clk=~Clk;

部分端口初始化及产生仿真的激励信号

   initial
		begin 
		  Do_Conv<=1'b0;
		  ADS_CHSEL<=8'b0;
		  ADS8344_DOUT<=1'b0;
		  Rst_n<=1'b0;
		  #(`clk_period*10+1);   //加1为了与时钟信号上升沿错开好观察
        Rst_n<=1'b1;
		  #(`clk_period*10)
		  
		  Do_Conv<=1'b1;
		  ADS8344_BUSY<=1'b0;
		  ADS_CHSEL<=8'b10000100;
		  #(`clk_period)
		  @(posedge (ADS8344_0.LSM_CNT==9'd97))
		    ADS8344_BUSY<=1'b1;
		  @(posedge (ADS8344_0.LSM_CNT==9'd109))
		    ADS8344_BUSY<=1'b0;
		  #(`clk_period*1000);
		  $stop;
		end 

给ADS_DOUT设置一个简单的数据输出信号

        initial 
		   begin
			  forever begin 
			    ADS8344_DOUT=~ADS8344_DOUT;
				 #100;
			  end 
			end

前仿真结果

复位为高电平
FPGA之ADS8344驱动程序
BUSY信号为低电平,ADS_DOUT开始输出转换数据
FPGA之ADS8344驱动程序
数据有效信号为1,ADS_DATA开始输出转换得到的数据;转换完成信号ASD_DONE变高电平,cs拉高。
FPGA之ADS8344驱动程序

仿真结果分析

按照前仿真结果来看,代码已经完成了ADS8344的驱动;本人未做板机验证,实际中是否能实现有待考究。

总结

小梅老师的设计方法让我受益匪浅,通过编写ADS8344的驱动让我对这种方法的掌握更加牢固,感谢小梅老师,感谢支持我的所有人。