設(shè)計(jì)背景:
數(shù)模轉(zhuǎn)換器(Digital to Analog Converter)即DAC,是數(shù)字世界和模擬世界之間的橋梁。人類(lèi)生活在模擬世界中,雖然數(shù)字器件及設(shè)備的比重日益增強(qiáng),但是DAC的發(fā)展仍是必不可少的。
從航空航天、國(guó)防軍事到民用通信、多媒體、數(shù)字信號(hào)處理等都涉及到DAC應(yīng)用。DAC基本上由4個(gè)部分組成,即權(quán)電阻網(wǎng)絡(luò)、運(yùn)算放大器、基準(zhǔn)電源和模擬開(kāi)關(guān)。它是一種將二進(jìn)制數(shù)字量形式的離散信號(hào)轉(zhuǎn)換成以參考電壓為基準(zhǔn)的模擬量的轉(zhuǎn)換器。
設(shè)計(jì)原理:
本設(shè)計(jì)采用串行數(shù)/模轉(zhuǎn)換芯片TLC5620,TLC5620是一個(gè)擁有四路輸出的數(shù)/模轉(zhuǎn)換器,時(shí)鐘頻率最大可達(dá)到1MHz。TLC5620芯片接口如下:
該芯片主要有以下特點(diǎn):四通道8位電壓輸出DA轉(zhuǎn)換器、5V單電源供電、串行接口、高阻抗基準(zhǔn)輸入、可編程1或2輸出范圍、同時(shí)更新設(shè)備、內(nèi)部上電復(fù)位、低功耗、半緩沖輸出。該芯片主要應(yīng)用于:可編程電源、數(shù)字控制放大器/誤差器、移動(dòng)通信、自動(dòng)測(cè)試設(shè)備、研發(fā)過(guò)程檢測(cè)和控制和信號(hào)合成等。
轉(zhuǎn)換公式:V = REF*(CODE/256)* (1+RNG)
V:實(shí)際電壓;REF:基準(zhǔn)電壓;CODE:輸入8位數(shù)據(jù);RNG:范圍。
TLC5620的接口時(shí)序如下列圖所示:
圖2 LDAC控制更新(LDAC為低電平)
圖3 LOAD控制更新(使用8位串行數(shù)據(jù),LOAD為低電平)
圖4 LDAC控制更新(使用8位串行數(shù)據(jù))
如圖1所示:當(dāng)LOAD為高電平時(shí),數(shù)據(jù)在CLK的下降沿被鎖存至DATA,只要所有數(shù)據(jù)被鎖存,則將LOAD拉低,將數(shù)據(jù)從串行輸入寄存器傳送到所選擇的DAC。
如圖2所示:串行編程期間LDAC為高電平,數(shù)據(jù)在LOAD為低電平時(shí)進(jìn)行鎖存,當(dāng)LDAC變?yōu)榈碗娖綍r(shí)傳送至DAC輸出。如圖3、4所示:輸入數(shù)據(jù)最高位(MSB)在前,數(shù)據(jù)傳輸使用兩個(gè)8個(gè)時(shí)鐘周期。
在本設(shè)計(jì)中運(yùn)用的是圖1的工作時(shí)序:
數(shù)據(jù)通道選擇:
RNG:控制DAC輸出范圍。當(dāng)RNG為低時(shí),輸出范圍在基準(zhǔn)電壓和GND之間;當(dāng)RNG為高時(shí),輸出范圍為兩倍的基準(zhǔn)電壓和GND。
設(shè)計(jì)架構(gòu)圖:
本設(shè)計(jì)驅(qū)動(dòng)TLC5620將輸入的數(shù)字量轉(zhuǎn)換為實(shí)際的模擬量(電壓),通過(guò)四個(gè)按鍵控制四路輸出的電壓變化,每按一次,電壓值也隨之上升,同時(shí)在數(shù)碼管上也依次顯示相應(yīng)的值(依次為A1,A0,RNG,輸入DATA)。本設(shè)計(jì)采用的開(kāi)發(fā)板的基準(zhǔn)電壓為2.5V。設(shè)計(jì)架構(gòu)圖如下所示:
key_test模塊通過(guò)四個(gè)按鍵輸入的值,組合輸出兩個(gè)數(shù)據(jù),11位的wr_data是TLC_DA模塊解碼所需的數(shù)據(jù)。20位的out_data是seg_num模塊數(shù)碼管顯示所需的數(shù)據(jù)。
設(shè)計(jì)代碼:
key_test模塊代碼如下:
0modulekey_test(//按鍵控制模塊
1//端口信號(hào):模塊的輸入輸出接口
2inputclk,//50MHZ
3inputrst_n,//低電平復(fù)位
4input[3:0]key,//四個(gè)按鍵組合信號(hào)
5
6output[10:0]wr_data,//輸出一幀數(shù)據(jù),為DA模塊的輸入數(shù)字量
7output[19:0]out_data //輸出數(shù)碼管顯示數(shù)據(jù)
8);
9
10//計(jì)數(shù)器時(shí)鐘分頻
11reg[30:0]cnt;
12regclk_r;//分頻時(shí)鐘:在消除抖動(dòng)的時(shí)鐘頻率下進(jìn)行按鍵的檢測(cè)
13always@(posedgeclkornegedgerst_n)//按鍵消抖,時(shí)間為0.2s進(jìn)行一次檢測(cè)
14if(!rst_n)
15begin
16cnt<=?0;
17clk_r<=?0;
18end
19elseif(cnt30'd1000_0000)
20cnt<=?cnt?+?1'b1;
21else
22begin
23cnt<=?0;
24clk_r<=?~clk_r;
25end
26
27//按鍵為低電平有效,當(dāng)檢測(cè)到對(duì)應(yīng)按鍵之后,相應(yīng)數(shù)值加1,并顯示相應(yīng)的通道
28reg[7:0]data;//按鍵輸入數(shù)據(jù)
29reg[1:0]channel;//通道選擇
30reg[7:0]key1,key2,key3,key4;//相應(yīng)四個(gè)按鍵
31always@(posedgeclk_rornegedgerst_n)
32if(!rst_n)
33begin
34key1<=?8'h00;
35key2<=?8'h00;
36key3<=?8'h00;
37key4<=?8'h00;
38data<=?8'h00;
39channel<=?2'b00;
40end
41else
42case(key)
434'b1110:begin//按鍵1:選擇通道A,且輸入數(shù)字量加1
44channel<=?2'b00;
45key1<=?key1?+?1'b1;
46data<=?key1;
47end
484'b1101:begin//按鍵2:選擇通道B,且輸入數(shù)字量加1
49channel<=?2'b01;
50key2<=?key2?+?1'b1;
51data<=?key2;
52end
534'b1011:begin//按鍵3:選擇通道C,且輸入數(shù)字量加1
54channel<=?2'b10;
55key3<=?key3?+?1'b1;
56data<=?key3;
57end
584'b0111:begin//按鍵4:選擇通道D,且輸入數(shù)字量加1
59channel<=?2'b11;
60key4<=?key4?+?1'b1;
61data<=?key4;
62end
63default:;
64endcase
65
66//用賦值語(yǔ)句將需要的數(shù)據(jù)組合起來(lái),在此例中將RNG默認(rèn)為1
67assignwr_data={channel,1'b1,data};assignout_data={{3'b000,channel[1]},3'b000,channel[0],4'h1,data};
68
69endmodule
TLC_DA模塊代碼如下:
0moduleTLC_DA(//輸入數(shù)字量轉(zhuǎn)換為模擬量模塊,本實(shí)驗(yàn)用TLC5620
1//端口信號(hào):模塊的輸入輸出接口
2inputclk,//系統(tǒng)時(shí)鐘50MHz
3inputrst_n,//低電平復(fù)位
4input[10:0]data_in,//輸入一幀數(shù)據(jù)
5outputda_data,//串行數(shù)據(jù)接口
6outputda_clk,//串行時(shí)鐘接口
7outputregda_ldac,//更新控制信號(hào)
8outputregda_load//串行加載控制接口
9);
10
11//計(jì)數(shù)器時(shí)鐘分頻:根據(jù)芯片內(nèi)部的時(shí)序要求進(jìn)行分頻
12reg[30:0]cnt;
13wireda_clk_r;//TLC 5620內(nèi)部時(shí)鐘信號(hào)
14always@(posedgeclkornegedgerst_n)//滿足協(xié)議中的時(shí)鐘要求,在TLC 5620中時(shí)鐘要求不大于1MHZ
15if(!rst_n)
16cnt<=?6'd0;
17else
18cnt<=?cnt?+?1'b1;
19
20assignda_clk_r=cnt[5];
21
22//接收時(shí)序狀態(tài)機(jī)
23reg[2:0]state;
24reg[3:0]cnt_da;
25regda_data_r;
26regda_data_en;//限定da_data,da_clk的有效區(qū)域
27always@(posedgeda_clk_rornegedgerst_n)
28if(!rst_n)
29begin
30state<=?0;
31cnt_da<=?0;
32da_load<=?1;
33da_ldac<=?0;???????????
34da_data_r<=?1'b1;
35da_data_en<=?0;
36end
37else
38case(state)
390:state<=?1;
401:begin
41da_load<=?1;
42da_data_en<=?1;
43if(cnt_da<=?10)
44begin
45cnt_da<=?cnt_da?+?1'b1;
46case(cnt_da)
470:da_data_r<=?data_in[10];
481:da_data_r<=?data_in[9];
492:da_data_r<=?data_in[8];
503:da_data_r<=?data_in[7];
514:da_data_r<=?data_in[6];
525:da_data_r<=?data_in[5];
536:da_data_r<=?data_in[4];
547:da_data_r<=?data_in[3];
558:da_data_r<=?data_in[2];
569:da_data_r<=?data_in[1];
5710:da_data_r<=?data_in[0];
58default:;
59endcase
60state<=?1;
61end
62else
63begin
64cnt_da<=?0;
65state<=?2;
66da_data_en<=?0;
67end
68end
692:begin
70da_load<=?0;
71state<=?3;
72end
733:begin
74da_load<=?1;
75state<=?0;
76end
77default:state<=?0;
78endcase
79
80assignda_data=(da_data_en)?da_data_r:1'b1;
81assignda_clk=(da_data_en)?da_clk_r:1'b0;
82
83endmodule
seg_num模塊代碼如下:
0moduleseg_num(//數(shù)碼管顯示模塊:選擇數(shù)碼管0-4共5個(gè)數(shù)碼管顯示{A1,A0,RNG,DATA}
1//端口信號(hào):模塊的輸入輸出接口
2inputclk,//系統(tǒng)時(shí)鐘50MHz
3inputrst_n,//低電平復(fù)位
4input[19:0]data_in,//20位輸入數(shù)據(jù)
5
6outputreg[7:0]seg,//數(shù)碼管段選
7outputreg[2:0]sel//數(shù)碼管位選
8);
9
10//通過(guò)查找表的方式,將相應(yīng)位的數(shù)碼管與數(shù)據(jù)的相應(yīng)位一一對(duì)應(yīng)
11reg[3:0]num;
12always@(*)
13case(sel)
144:num=data_in[3:0];//第五個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[3:0]
153:num=data_in[7:4];//第四個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[7:4]
162:num=data_in[11:8];//第三個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[11:8]
171:num=data_in[15:12];//第二個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[15:12]
180:num=data_in[19:16];//第一個(gè)數(shù)碼管顯示數(shù)據(jù)的低四位[19:16]
19default:;
20endcase
21
22//通過(guò)查找表的方式,將數(shù)據(jù)與數(shù)碼管的顯示方式一一對(duì)應(yīng)
23always@(*)
24case(num)
250:seg<=?8'hC0;???//8'b1100_0000
261:seg<=?8'hF9;???//8'b1111_1001
272:seg<=?8'hA4;??//8'b1010_0100 ?
283:seg<=?8'hB0;???//8'b1011_0000
294:seg<=?8'h99;???//8'b1001_1001
305:seg<=?8'h92;???//8'b1001_0010
316:seg<=?8'h82;???//8'b1000_0010
327:seg<=?8'hF8;???//8'b1111_1000
338:seg<=?8'h80;???//8'b1000_0000
349:seg<=?8'h90;???//8'b1001_0000
35default:seg<=?8'hFF;?//8'b1111_1111
36endcase
37
38//計(jì)數(shù)器時(shí)鐘分頻:用cnt第10位的變化作為分頻時(shí)鐘
39reg[23:0]cnt;
40always@(posedgeclkornegedgerst_n)
41if(!rst_n)
42cnt<=?4'd0;
43else
44cnt<=?cnt?+?1'b1;
45//在分頻時(shí)鐘下,數(shù)碼管的0-5位依次循環(huán)
46always@(posedgecnt[10]ornegedgerst_n)//分頻時(shí)鐘為2^10/50M
47if(!rst_n)
48sel<=?0;
49elseif(sel4)
50sel<=?sel?+?1'b1;
51else
52sel<=?0;???
53
54endmodule
top頂層模塊代碼如下:
0moduletop(//頂層模塊:將各個(gè)模塊組合
1//外部接口
2inputclk,//系統(tǒng)時(shí)鐘50MHz
3inputrst_n,//低電平復(fù)位
4input[3:0]key,//四個(gè)按鍵組成的按鍵信號(hào),低電平有效
5
6outputda_data,//DA串行接口數(shù)據(jù)
7outputda_clk,//DA串行接口時(shí)鐘
8outputda_ldac,//DA更新信號(hào)
9outputda_load,//DA串行接口加載控制信號(hào)
10output[7:0]seg,//數(shù)碼管段選
11output[2:0]sel//數(shù)碼管位選
12);
13//內(nèi)部信號(hào):模塊內(nèi)部的接口信號(hào),比如模塊TLC_DA的輸出信號(hào)data_in,通過(guò)內(nèi)部信號(hào)r_data與模塊key_test的輸入信號(hào)wr_data相連
14wire[10:0]wr_data;
15wire[19:0]out_data;//輸入給數(shù)碼管的數(shù)據(jù)
16
17//模塊例化
18TLC_DATLC_DA_inst(//輸入數(shù)字量轉(zhuǎn)換為模擬量模塊
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
28key_testkey_test_inst(//按鍵控制模塊
29.clk(clk),
30.rst_n(rst_n),
31.key(key),
32.wr_data(wr_data),
33.out_data(out_data)
34);
35
36seg_numseg_num_inst(//數(shù)碼管顯示模塊
37.clk(clk),
38.rst_n(rst_n),
39.data_in(out_data),
40.seg(seg),
41.sel(sel)
42);
43
44endmodule
test頂層模塊測(cè)試代碼:
0`timescale1ns/1ns//設(shè)置仿真時(shí)間單位與精度分別為1ns/1ns
1//若設(shè)為`timescale 1ns/1ps (#200就是延時(shí)200 ns; 1ps就是仿真的精度)
2moduletest;//測(cè)試模塊:主要是將激勵(lì)信號(hào)賦相應(yīng)的值,仿真之后觀察波形,驗(yàn)證與實(shí)際功能是否一樣
3
4//端口信號(hào)定義,激勵(lì)信號(hào)為reg型
5regclk;
6regrst_n;
7reg[3:0]key;
8wire[7:0]seg;
9wire[2:0]sel;
10
11//模塊例化
12toptop(
13.clk(clk),
14.rst_n(rst_n),
15.key(key),
16.seg(seg),
17.sel(sel)
18);
19
20//初始化激勵(lì),以及給相應(yīng)激勵(lì)賦值
21initial
22begin
23clk=0;rst_n=0;key=4'b1111;//在復(fù)位階段,將激勵(lì)賦初值
24
25#200rst_n=1;//在延時(shí)200ns后將復(fù)位信號(hào)置為1
26
27//實(shí)現(xiàn)按鍵1開(kāi),關(guān)
28#500000key=4'b1110;
29#500000key=4'b1111;
30
31end
32
33always#10clk=~clk;//時(shí)鐘的表示,即每隔10ns翻轉(zhuǎn)一次,一個(gè)周期的時(shí)間即為20ns,時(shí)鐘為1/20ns = 50MHZ
34
35endmodule
仿真圖:
由于仿真時(shí)間原因,這里只測(cè)試按鍵1按下時(shí)的數(shù)碼管顯示,顯示為00100,表示通道A,RNG為1,輸入數(shù)字量為00。之后實(shí)際下板驗(yàn)證,用萬(wàn)用表也可測(cè)出輸入數(shù)字量對(duì)應(yīng)的電壓值。
-
dac
+關(guān)注
關(guān)注
43文章
2291瀏覽量
190974 -
數(shù)字信號(hào)處理
+關(guān)注
關(guān)注
15文章
560瀏覽量
45839 -
數(shù)模轉(zhuǎn)換器
+關(guān)注
關(guān)注
14文章
1011瀏覽量
83166
原文標(biāo)題:【FPGA學(xué)習(xí)】一文教你輕松實(shí)現(xiàn)數(shù)模轉(zhuǎn)換的設(shè)計(jì)
文章出處:【微信號(hào):elecfans,微信公眾號(hào):電子發(fā)燒友網(wǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論