1. 程式人生 > >PMODAD1 實現模擬資料的採集 時序篇

PMODAD1 實現模擬資料的採集 時序篇

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顯示採集的數值,並用線上邏輯分析儀觀察效果。