設計背景:
數(shù)模轉換器是連接數(shù)字世界和模擬世界的橋梁。人類生活在模擬世界。雖然數(shù)字器件和設備的比例日益增加,但數(shù)模轉換器的發(fā)展仍然是必要的。
DAC應用涉及航空空航天、國防和軍事、民用通信、多媒體和數(shù)字信號處理。DAC基本上由四部分組成,分別是權重電阻網(wǎng)絡、運算放大器、參考電源和模擬開關。它是一種轉換器,根據(jù)參考電壓將二進制數(shù)字量形式的離散信號轉換為模擬量。
設計原則:
本設計采用串行數(shù)模轉換器芯片TLC5620。TLC5620為四路輸出的數(shù)模轉換器,時鐘頻率最多可達1MHz。TLC5620芯片的接口如下:
該芯片主要具有以下特點:四通道8位電壓輸出DA轉換器,5V單電源,串行接口,高阻抗基準輸入,可編程1或2輸出范圍,設備同步更新,內(nèi)部上電復位,低功耗,半緩沖輸出。該芯片主要用于可編程電源、數(shù)控放大器/誤差檢測器、移動通信、自動測試設備、R&D過程檢測與控制和信號合成等。
變換公式:V = REF*(CODE/256)* (1+RNG)
v:實際電壓;參考電壓;代碼:輸入8位數(shù)據(jù);RNG:范圍。
TLC5620的接口時序如下圖所示:
圖1負荷控制更新(LDAC低)
圖2 LDAC控制更新(LDAC低)
圖3負載控制更新(使用8位串行數(shù)據(jù),負載低)
圖4 LDAC控制更新(使用8位串行數(shù)據(jù))
如圖1所示,當LOAD為高電平時,數(shù)據(jù)在CLK下降沿鎖存為數(shù)據(jù),只要所有數(shù)據(jù)都鎖存,LOAD就會拉低,將數(shù)據(jù)從串行輸入寄存器傳輸?shù)竭x定的數(shù)模轉換器。
如圖2所示,在串行編程期間,LDAC為高,當負載為低時,數(shù)據(jù)被鎖存,當LDAC為低時,數(shù)據(jù)被傳輸?shù)綌?shù)模轉換器輸出。如圖3和圖4所示,輸入數(shù)據(jù)的最高有效位(MSB)首先出現(xiàn),數(shù)據(jù)傳輸使用兩個8時鐘周期。
在本設計中,使用了圖1的工作順序:
數(shù)據(jù)通道選擇:
RNG:控制數(shù)模轉換器的輸出范圍。當RNG低時,輸出范圍在參考電壓和GND之間。當RNG為高電平時,輸出范圍是參考電壓和GND的兩倍。
設計架構圖:
本設計驅動TLC5620將輸入的數(shù)字量轉換成實際的模擬量(電壓),并通過四個按鈕控制四個輸出的電壓變化。每次按下按鈕,電壓值都會上升,相應的值(A1,A0,RNG,輸入數(shù)據(jù))會依次顯示在數(shù)碼管上。本次設計使用的開發(fā)板參考電壓為2.5V,設計架構圖如下:
key_test模塊通過組合四個按鍵輸入的值輸出兩個數(shù)據(jù),11位wr_data是TLC_DA模塊解碼所需的數(shù)據(jù)。20位out_data是seg_num模塊數(shù)碼管顯示所需的數(shù)據(jù)。
設計代碼:
key_test模塊代碼如下:
0模塊key_test( //按鍵控制模塊
1 //端口信號:模塊的輸入輸出接口
2輸入clk,//50MHZ
3輸入rst_n,//低電平復位
4輸入[3:0]鍵,//四鍵組合信號
五
6輸出[10:0] wr_data,//輸出一幀數(shù)據(jù),是DA模塊的輸入數(shù)字量
7輸出[19:0] out_data //輸出數(shù)碼管顯示數(shù)據(jù)
8 );
九
10 //分頻計數(shù)器時鐘
11 reg[30:0]CNT;
12 reg clk _ r;//分頻時鐘:在消除抖動的時鐘頻率下執(zhí)行按鍵檢測
13總是@ (posedgclk或negerst _ n)//按鍵去抖,一次測試時間為0.2s
14 if(!rst_n)
15開始
16 cnt <。= 0;
17 clk_r <。= 0;
18結束
19 else if(cnt <。30'd1000_0000)
20 cnt <。= CNT+1 ' B1;
其他21個
22開始
23 cnt <。= 0;
24 clk_r <。= ~ clk _ r;
25結束
26
27 //鍵低電平有效。當檢測到相應的鍵時,相應的值增加1并顯示相應的頻道
28 reg [7:0]數(shù)據(jù);//按鍵輸入數(shù)據(jù)
29 reg [1:0]通道;//頻道選擇
30 reg [7:0] key1,key2,key3,key4//對應四個按鈕
31始終@(posedge clk_r或negedge rst_n)
32 if(!rst_n)
33開始
34 key1 <。= 8 ' h00
35 key2 <。= 8 ' h00
36 key3 <。= 8 ' h00
37 key4 <。= 8 ' h00
38數(shù)據(jù)<。= 8 ' h00
39頻道<。= 2 ' b00
40結束
41 else
42箱(鑰匙)
43 4'b1110: begin //按鈕1:選擇頻道A,在輸入號碼上加1
44頻道<。= 2 ' b00
45 key1 <。= key 1+1 ' B1;
46數(shù)據(jù)<。= key1
47結束
48 4'b1101: begin //按鈕2:選擇頻道B,在輸入號碼上加1
49頻道<。= 2 ' b01
50 key2 <。= key 2+1 ' B1;
51數(shù)據(jù)<。= key2
52結束
53 4'b1011: begin //按鈕3:選擇頻道C,并在輸入號碼上加1
54頻道<。= 2 ' b10
55 key3 <。= key 3+1 ' B1;
56數(shù)據(jù)<。= key3
57結束
58 4'b0111: begin //鍵4:選擇頻道D,在輸入號碼上加1
59頻道<。= 2 ' b11
60 key4 <。= key 4+1 ' B1;
61數(shù)據(jù)<。= key4
62結束
63默認值:;
64端箱
65
66 //將所需數(shù)據(jù)與賦值語句結合起來。在本例中,RNG默認為1
67 assign wr_data = {channel,1'b1,data };assignout_data={{3'b000,channel[1]},3'b000,channel[0],4'p,data };
六十八
69端模塊
TLC_DA模塊代碼如下:
0模塊TLC_DA( //將數(shù)字量輸入到模擬量模塊,本實驗采用TLC5620
1 //端口信號:模塊的輸入輸出接口
2輸入clk,//系統(tǒng)時鐘50MHz
3輸入rst_n,//低電平復位
4輸入[10:0] data_in,//輸入一幀數(shù)據(jù)
5輸出da_data,//串行數(shù)據(jù)接口
6輸出da _ clk//串行時鐘接口
7輸出reg da_ldac,//更新控制信號
8輸出寄存器da_load //串行負載控制接口
9 );
10
11 //計數(shù)器時鐘分頻:根據(jù)芯片內(nèi)部時序要求分頻
12 reg[30:0]CNT;
13線da _ clk _ r;//TLC 5620內(nèi)部時鐘信號
14始終@ (posedgclk或negerst _ n)//滿足協(xié)議中的時鐘要求,TLC 5620中的時鐘要求不超過1MHZ。
15 if(!rst_n)
16 cnt <。= 6 ' d0
17其他
18 cnt <。= CNT+1 ' B1;
19
20分配da _ clk _ r = CNT[5];
21
22 //接收定時狀態(tài)機
23 reg [2:0]狀態(tài);
24 reg[3:0]CNT _ da;
25 reg da _ data _ r;
26 reg da _ data _ en//定義da _ data和da _ clk的有效區(qū)域
27始終@(posedge da_clk_r或negedge rst_n)
28 if(!rst_n)
29開始
30州<。= 0;
31 cnt _ da & lt= 0;
32 da _ load & lt= 1;
33 da _ ldac & lt= 0;
34 da _ data _ r & lt= 1 ' b1
35 da _ data _ en & lt= 0;
36端
37 else
38起案件(州)
39 0:狀態(tài)<。= 1;
40 1:開始
41 da _ load & lt= 1;
42 da _ data _ en & lt= 1;
43 if(CNT _ da & lt;= 10)
44開始
45 cnt _ da & lt= CNT _ da+1 ' B1;
46箱(cnt_da)
47 0:da _ data _ r & lt;= data _ in[10];
48 1:da _ data _ r & lt;= data _ in[9];
49 2:da _ data _ r & lt;= data _ in[8];
50 3:da _ data _ r & lt;= data _ in[7];
51 4:da _ data _ r & lt;= data _ in[6];
52 5:da _ data _ r & lt;= data _ in[5];
53 6:da _ data _ r & lt;= data _ in[4];
54 7:da _ data _ r & lt;= data _ in[3];
55 8:da _ data _ r & lt;= data _ in[2];
56 9:da _ data _ r & lt;= data _ in[1];
57 10:da _ data _ r & lt;= data _ in[0];
58默認值:;
59端箱
60州<。= 1;
61結束
62 else
63開始
64 cnt _ da & lt= 0;
65州<。= 2;
66 da _ data _ en & lt= 0;
67結束
68端
69 2:開始
70 da _ load & lt= 0;
71州<。= 3;
72結束
73 3:開始
74 da _ load & lt= 1;
75州<。= 0;
76端
77默認值:state <。= 0;
78端箱
79
80賦值da_data = (da_data_en)?da _ data _ r:1 ' B1;
81賦值da_clk = (da_data_en)?da _ clk _ r:1 ' B0;
82
83端模塊
Seg_num模塊代碼如下:
0模塊seg_num( //數(shù)碼管顯示模塊:選擇數(shù)碼管0-4顯示{A1,A0,RNG,DATA}。
1 //端口信號:模塊的輸入輸出接口
2輸入clk,//系統(tǒng)時鐘50MHz
3輸入rst_n,//低電平復位
4輸入[19:0] data_in,//20位輸入數(shù)據(jù)
五
6輸出寄存器[7:0] seg,//數(shù)字管段選擇
7輸出寄存器[2:0] sel //數(shù)字電子管位選擇
8 );
九
10 //通過查找表,對應位的數(shù)碼管與對應的數(shù)據(jù)位一一對應
11 reg[3:0]num;
12總是@(*)
13箱(sel)
14 4:num = data _ in[3:0];//第五個數(shù)碼管顯示低四位數(shù)據(jù)[3: 0]
15 3:num = data _ in[7:4];//第四個數(shù)碼管顯示低四位數(shù)據(jù)[7: 4]
16 ^ 2:num = data _ in[11:8];//第三個數(shù)碼管顯示低四位數(shù)據(jù)[11:8]
17 1:num = data _ in[15:12];//第二個數(shù)碼管顯示低四位數(shù)據(jù)[15:12]
18 0:num = data _ in[19:16];//第一個數(shù)碼管顯示低四位數(shù)據(jù)[19:16]
19默認值:;
20端箱
21
22 //借助查表,數(shù)據(jù)一一對應數(shù)碼管的顯示方式。
23總是@(*)
24箱(數(shù)量)
25 0: seg <。= 8 ' hC0//8'b1100_0000
26 1: seg <。= 8 ' hF9//8'b1111_1001
27 2: seg <。= 8 ' hA4//8'b1010_0100
28 3: seg <。= 8 ' hB0//8'b1011_0000
29 4: seg <。= 8 ' h99//8'b1001_1001
30 5: seg <。= 8 ' h92//8'b1001_0010
31 6: seg <。= 8 ' h82//8'b1000_0010
32 7: seg <。= 8 ' hF8//8'b1111_1000
33 8: seg <。= 8 ' h80//8'b1000_0000
34 9: seg <。= 8 ' h90//8'b1001_0000
35默認值:seg <。= 8 ' hFF//8'b1111_1111
36端箱
37
38 //計數(shù)器時鐘分頻:cnt位10的變化用作分頻時鐘
39 reg[23:0]CNT;
40始終@(posedge clk或negedge rst_n)
41 if(!rst_n)
42 cnt <。= 4 ' d0
43 else
44 cnt <。= CNT+1 ' B1;
45 //在分頻時鐘下,數(shù)碼管的0-5位依次循環(huán)
46的分頻時鐘總是@ (posedgcnt [10]或negerst _ n)//是2 ^ 10/50m
47 if(!rst_n)
48 sel <。= 0;
49 else if(sel & lt;4)
50 sel <。= sel+1 ' B1;
51 else
52 sel <。= 0;
53
54端模塊
頂部模塊代碼如下:
0模塊頂部(//頂部模塊:組合各種模塊
1 //外部接口
2輸入clk,//系統(tǒng)時鐘50MHz
3輸入rst_n,//低電平復位
4輸入[3:0]鍵,//由四個鍵組成的鍵信號,低電平有效
五
6輸出da_data,//DA串行接口數(shù)據(jù)
7輸出da_clk,//DA串行接口時鐘
8輸出da_ldac,//DA更新信號
9輸出da_load,//DA串行接口負載控制信號
10輸出[7:0] seg,//數(shù)字管段選擇
11輸出[2:0] sel //數(shù)字電子管位選擇
12 );
13 //內(nèi)部信號:模塊的內(nèi)部接口信號,如模塊TLC_DA的輸出信號data_in,通過內(nèi)部信號r_data與模塊key_test的輸入信號wr_data相連
14線[10:0]wr _ data;
15線[19:0]out _ data;//數(shù)字管的數(shù)據(jù)輸入
16
17 //模塊實例化
18 TLC_DA TLC_DA_inst( //將數(shù)字量輸入模擬量模塊)
19 .clk(clk),
20 .rst_n(rst_n),
21 .da_clk(da_clk),
22 .da_data(da_data),
23 .da_ldac(da_ldac),
24 .da_load(da_load),
25 .data_in(wr_data)
26 );
27
28 key_test key_test_inst( //按鍵控制模塊)
29 .clk(clk),
30 .rst_n(rst_n),
31 .鍵(key),
32 .wr_data(wr_data),
33 .out_data(out_data)
34 );
35
36 seg_num seg_num_inst( //數(shù)碼管顯示模塊)
37 .clk(clk),
38 .rst_n(rst_n),
39 .data_in(out_data),
40 .seg(seg),
41 .sel(sel)
42 );
43
44端模塊
測試頂部模塊測試代碼:
0 '時間刻度1 ns/ 1 ns //將模擬時間單位和精度分別設置為1 ns/ 1 ns
1 //如果設置為`時標1ns/1ps (# 200表示延遲200 ns1ps是模擬的精度)
2模塊測試;//測試模塊:主要是給激勵信號賦值,模擬后觀察波形,驗證是否與實際功能相同
三
4 //端口信號定義,激勵信號為reg類型
5 reg clk
6 reg rst _ n;
7 reg [3:0]鍵;
8線[7:0]seg;
9線[2:0]sel;
10
11 //模塊實例化
12頂頂(
13 .clk(clk),
14 .rst_n(rst_n),
15 .鍵(key),
16 .seg(seg),
17 .sel(sel)
18 );
19
20 //初始化激勵,并為相應的激勵賦值
21首字母
22開始
23 clk = 0;rst _ n = 0;key = 4 ' b1111//在復位階段,將激勵設置為初始值
24
25 # 200 rst _ n = 1;//延遲200ns后,將復位信號設置為1
26
27 //實現(xiàn)按鍵1打開和關閉
28 # 500000 key = 4 ' b1110
29 # 500000 key = 4 ' b1111
30
31結束
32
33始終# 10 clk = ~ clk//時鐘的表示,即每10ns,一個周期的時間為20ns,時鐘為1/20ns = 50MHZ
34
35端模塊
模擬圖:
由于模擬時間的原因,這里只測試按下按鈕1時數(shù)碼管的顯示,顯示為00100,表示頻道A,RNG為1,輸入數(shù)字為00。實際板卡驗證后,也可以用萬用表測量輸入數(shù)字量對應的電壓值。
1.《數(shù)模轉換原理 【FPGA學習】一文教你輕松實現(xiàn)數(shù)模轉換的設計》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡信息知識,僅代表作者本人觀點,與本網(wǎng)站無關,侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《數(shù)模轉換原理 【FPGA學習】一文教你輕松實現(xiàn)數(shù)模轉換的設計》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉載時請保留本站內(nèi)容來源地址,http://f99ss.com/caijing/796867.html