FPGA驱动AD芯片之实现与芯片通信

描述

概述: 利用FPGA实现AD芯片的时序,进一步实现与AD芯片数据的交互,主要熟悉FPGA对时序图的实现,掌握时序图转换Verilog硬件描述语言技巧后与其它芯片进行数据的交互也是类似的。

说明: FPGA芯片采用了altera的Cyclon IV E系列的“EP4CE10F17C8”,软件环境-Quartus-Ⅱ,采用的AD芯片为—AD-TLC549。

通过FPGA实现以下时序设计:

FPGA

1.AD-TLC549简介

位数:8位。
最大转换时间:17us(36个内部时钟周期)。
转换速率:每秒40000次。
TOP VIEW:

FPGA


电路连接图:

FPGA

2.AD-TLC549时序图解析

From datasheet:

FPGA

2.1时序图说明:

(1) 当CS为高时,转换结果数据串行输出端DATA OUT处于高阻态,此时I/O CLOCK也不起作用。
(2) 当CS为低时,AD前一次转换的数据A的最高位A7立即出现在数据线DATA OUT上,其余的7位数据在I/O CLOCK的下降沿依次由时钟同步输出(方便我们在上升沿采集数据,细品)。

注意:

① 当CS变为低电平到I/O CLOCK的第一个时钟到来至少需要1.4us。

FPGA
② I/O CLOCK不能超过1.1M,Verilog代码中采用了1M的时钟。

FPGA


(3) 读完8位数据后,AD开始转换下一帧 数据B,以便下次读取,转换时片选信号CS必须置高电平,每次转换的时间不超过17us,转换开始于CS变低后的I/O CLOCK的第8个下降沿,没有转换完成的标志信号;也没有启动控制端,只要读取前一次数据后马上就可以开始新的AD转换,转换完后就进入保持状态。
FPGA

3.时序图转化为Verilog代码

在时序图转化为Verilog代码过程中,要注意的是时间 t su {{ ext{t}}_{{ ext{su}}}} tsu=1.4us、 t conv {{ ext{t}}_{{ ext{conv}}}} tconv=17us、I/O CLOCK=1MHz,AD转换的时候I/O CLOCK是没有的。

FPGA


FPGA
FPGA

(1)代码TOP VIEW:

FPGA


(2)代码按以下状态机编写:

FPGA


状态1:CS拉低至CLK第一个上升沿。
状态2:在I/O CLOCK8个上升沿读取数据。
状态3:等待AD转换完成。
状态4:AD转换完完成。

(3)依据时序图完成以下代码:

 

 

//系统时钟为50M,周期为20ns; AD时钟为1M,周期为1us

`define Tsu_time 10'd70//70*20=1.4us,Tsu延时的计数终值
`define Cov_time 10'd850//850*20=17us, Cov延时的计数终值
`define CLK_time 10'd50//20*50=1us,  实现1M AD时钟得计数终值
`define CLKHALF_time 10'd25//20*25=0.5us,实现1M AD时钟得计数中值

module AD_TLC549
(
//输入
inputCLK_50M,//系统时钟
input RST_N,//复位
input AD_DATA,//8bit AD原始数据
//输出
output reg AD_CS,//片选
output reg AD_CLK//AD时钟1M
);

//状态机,四个状态;状态1:CS拉低至CLK第一个上升沿,状态2:读取数据,状态3等待转换,状态4:转换完成
reg [2:0]SM_NOW/*synthesis preserve*/; //现在的状态
reg [2:0]SM_NEXT/*synthesis preserve*/;//下一状态
parameter SM_Tsu= 3'd0, //CS拉低至CLK第一个上升沿1.4us
SM_Data = 3'd1, //读取AD数据8个AD_CLK
SM_Cov= 3'd2, //等待转换17us
SM_End= 3'd3; //转换完成

//产生计数
reg[9:0] Time_cnt;//在状态机的每个状态开始都会被清零,可以运用至每个状态的计数
reg[3:0] CLK_posedge;//AD_CLK 的8个时钟上升沿

//读取的8bit数据
reg[7:0]DATA;//数据现态
reg[7:0]    DATA_N/*synthesis preserve*/;//数据的下一个状态


//时钟
reg AD_CLK_N;//AD_CLK的下一个状态


//时序产生,Tsu计时、Cov计时、AD_CLK计时
always@(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
Time_cnt <= 10'd0;
else if(SM_NOW != SM_NEXT)
Time_cnt <= 10'd0;
else if(SM_NOW == SM_Tsu)//产生tus延时
begin
if(Time_cnt == `Tsu_time)
Time_cnt <= 10'd0;
else
Time_cnt <= Time_cnt + 10'd1;
end
else if(SM_NOW == SM_Cov)//产生Cov延时
begin
if(Time_cnt == `Cov_time)
Time_cnt <= 10'd0;
else
Time_cnt <= Time_cnt + 10'd1;
end
else if(SM_NOW == SM_Data)//产生CLK
begin
if(Time_cnt == `CLK_time)
Time_cnt <= 10'd0;
else
Time_cnt <= Time_cnt + 10'd1;
end
else
Time_cnt <= Time_cnt;
end

//产生AD_CLK
always@(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
AD_CLK <= 0;
else
AD_CLK <= AD_CLK_N;
end
always@(*)
begin
if(SM_NOW != SM_Data)
AD_CLK_N = 0;
else if(Time_cnt == `CLKHALF_time)//半周期
begin
AD_CLK_N = 1;//CLK_H
end
else if(Time_cnt == `CLK_time)//满周期
AD_CLK_N = 0;//CLK_L
else
AD_CLK_N = AD_CLK;
end

//记录AD_CLK的8个上升沿
always@(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
CLK_posedge <= 4'd0;
else if(SM_NOW != SM_Data)
CLK_posedge <= 4'd0;
else if(Time_cnt == `CLKHALF_time)
CLK_posedge <= CLK_posedge + 4'd1;
else
CLK_posedge <= CLK_posedge;
end

//CS信号产生
always@(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
AD_CS <= 1'b1;
else
begin
if(SM_NOW == SM_Tsu)
AD_CS <= 1'b0;
else if(SM_NOW == SM_Cov)
AD_CS <= 1'b1;
else
AD_CS <= AD_CS;
end
end


//状态机,产生AD时序
always@(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
SM_NOW <= 3'd0;
else
SM_NOW <= SM_NEXT;
end
always@(*)
begin
case(SM_NOW)
SM_Tsu://状态1:CS拉低至CLK第一个上升沿。
if(Time_cnt == `Tsu_time)
SM_NEXT = SM_Data;
else
SM_NEXT = SM_Tsu;
SM_Data://状态2:在I/O CLOCK8个上升沿读取数据。
if(CLK_posedge == 4'd8 && Time_cnt == `CLK_time)
SM_NEXT = SM_Cov;
else
SM_NEXT = SM_Data;
SM_Cov: //状态3:等待AD转换完成。
if(Time_cnt == `Cov_time)
SM_NEXT = SM_End;
else
SM_NEXT = SM_Cov;
SM_End://状态4:AD转换完完成。
 SM_NEXT <= SM_Tsu;
default:SM_NEXT <= SM_Tsu;
endcase
end



//提取数据
always@(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
DATA <= 8'b0;
else
DATA <= DATA_N;
end

always@(*)
begin
if((SM_NOW == SM_Data)&&(!AD_CLK)&&(AD_CLK_N))//上升沿
DATA_N = {DATA[6:0],AD_DATA};
else
DATA_N = DATA;
end

endmodule

 

 

4. 仿真结果

通过SignalTapⅡ仿真得到以下波形:

FPGA


波形解析:

(1) t su {{ ext{t}}_{{ ext{su}}}} tsu:
用计数器实现了1.9us延时,大于了1.4us。

FPGA

(2) t conv {{ ext{t}}_{{ ext{conv}}}} tconv:
用计数器实现17us延时

FPGA


(3) 8bit数据及其时钟:

FPGA

原文链接:

https://openatomworkshop.csdn.net/6746bf193a01316874d9466f.html

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分