您的位置:首页 > 产品设计 > 产品经理

PMODAD1 实现模拟数据的采集 时序篇

2017-06-30 12:04 831 查看
AD7476是采用类似SPI的串行接口实现接入主控设备。



我们看数据手册,这里有三根线 SCLK,CS,SDATA。我们看看时序:


其中CS和SCLK是主控端(FPGA或者单片机),SDATA是7476的输出。这个波形一看,我们就知道可以使用计数器实现。



根据我们图上标注的红色的数字,可以做一个计数器,数值从0-34循环。CS在0时候开始输出0,在33时候开始输出1,而当计数器数值是8,10,这些时钟的上升边缘时,SDATA数据已经READY可以被打入寄存器。这里注意上第一红线位置我们看到是8,9之间,那应该取8还是9呢,我们看到数据DB11和8同时就绪的,所以应该取吧,他们是时钟对齐的。

这样一个采集周期用了35时钟周期,而一个采集周期是1US(因为7476是1M 的采样速率),这样就要求我们采集器的时钟周期是35M。有了以上分析,代码呼之欲出。我们简单写写。

module ad7476_sample(
input clk,rst,
input  ADC_sdata,
output reg ADC_sclk,ADC_csn,
output reg [11:0]  adc_res,
output reg   adc_valid

);

reg [7:0] cntr ;
always @ (posedge clk) //clk 35MHZ
if (rst)cntr<=0;else if (cntr == 34) cntr<=0;else cntr<=cntr+1;

always @ (posedge clk)
case (cntr )
0:  ADC_csn <= 0;
33:  ADC_csn <= 1;
endcase
always @ (posedge clk)
case (cntr)
//0,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,34 :
34,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,33 :ADC_sclk<=1;
default ADC_sclk<=0;
endcase
always @ (posedge clk)
case (cntr )
8: adc_res[11] <= ADC_sdata ;
10:adc_res[10] <= ADC_sdata ;
12:adc_res[9] <= ADC_sdata ;
14:adc_res[8] <= ADC_sdata ;
16:adc_res[7] <= ADC_sdata ;
18:adc_res[6] <= ADC_sdata ;
20:adc_res[5] <= ADC_sdata ;
22:adc_res[4] <= ADC_sdata ;
24:adc_res[3] <= ADC_sdata ;
26:adc_res[2] <= ADC_sdata ;
28:adc_res[1] <= ADC_sdata ;
30:adc_res[0] <= ADC_sdata ;
endcase

always @ (posedge clk)adc_valid <= cntr == 32 ;

endmodule
上述代码信手拈来,没有编译可能存在笔误。

这里用到了一个adc_valid来采集的数据已经更新了,可以用来做下游数据控制的写信号。

我们看到根据时序来构造控制逻辑是很简单的,读者可以打印下时序图,之后用笔在上面画画,确定一下计数器的分配,思路明细之后就可以编程了。

这里思路其实是状态机,但是有由于几乎没有输入信号控制状态的转移,实际上也就成了计数器。于是设置一个主计数器循环运转,其他always块根据当前计数器数值决定自己具体做点什么。

下一篇BLOG将介绍在VIVADO里面用纯逻辑实现,在使用LED显示采集的数值,并用在线逻辑分析仪观察效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: