設(shè)計(jì)背景:
模數(shù)轉(zhuǎn)換器,又稱A/D轉(zhuǎn)換器,簡稱ADC,通常是指一個(gè)將模擬信號轉(zhuǎn)換為抗干擾性更強(qiáng)的數(shù)字信號的電子器件。一般的ADC是將一個(gè)輸入電壓信號轉(zhuǎn)換為一個(gè)輸出的數(shù)字信號。由于數(shù)字信號本身不具有實(shí)際意義,僅僅表示一個(gè)相對大小,故任何一個(gè)ADC都需要一個(gè)參考模擬量作為轉(zhuǎn)換標(biāo)準(zhǔn)。比較常見的參考標(biāo)準(zhǔn)為最大的可轉(zhuǎn)換信號大小,而輸出的數(shù)字量則表示輸入信號相對于參考信號的大小。本設(shè)計(jì)則通過對模數(shù)轉(zhuǎn)換芯片(TLC549)的采樣控制,實(shí)現(xiàn)一個(gè)簡易的數(shù)字電壓表。
設(shè)計(jì)原理:
TLC549典型的配置電路如下圖所示:
TLC549的端口描述如下:
TLC549是一個(gè)8位的串行模數(shù)轉(zhuǎn)換器,A/D轉(zhuǎn)換時(shí)間最大為17us,最大轉(zhuǎn)換速率為4MHz。下圖為TLC549的訪問時(shí)序,從圖中可以看出,TLC549的使用只需對外接輸入輸出時(shí)鐘(I/O CLK)和芯片選擇(/CS)、輸入的模擬信號(ANALOG IN)的控制。
分析時(shí)序圖可知:當(dāng)片選信號(/CS)拉低時(shí),ADC前一次的轉(zhuǎn)換數(shù)據(jù)(A)的最高位A7立即出現(xiàn)在數(shù)據(jù)線DATA OUT上,之后的數(shù)據(jù)在時(shí)鐘I/O CLOCK的下降沿改變,可在I/O CLOCK的上升沿讀取數(shù)據(jù)。轉(zhuǎn)換時(shí),/CS要置為高電平。在設(shè)計(jì)操作時(shí),要注意Tsu(CS)、Tconv、Twh(CS)和I/O CLOCK的頻率這幾個(gè)參數(shù)。Tsu(CS)為CS拉低到I/O CLOCK第一個(gè)時(shí)鐘到來的時(shí)間,至少要1.4us;Twh(CS)為ADC的轉(zhuǎn)換時(shí)鐘,不超過17us,Tconv的值也不超過17us;I/O CLOCK為 1.1MHz。其他參數(shù)可參考數(shù)據(jù)手冊。
由于ADC是8位的,所以采樣的電壓值為:
V =(D*Vref)/256
其中V為采樣的電壓值;D為ADC轉(zhuǎn)換后讀取的8位二進(jìn)制數(shù);Vref為參考電壓值,此處為2.5V。
設(shè)計(jì)架構(gòu)圖:
本設(shè)計(jì)通過調(diào)節(jié)電位器RW1改變ADC的模擬輸入值,數(shù)據(jù)采樣讀取后由數(shù)碼管顯示,最后用萬用表測量輸入電壓,并與讀取在數(shù)碼管上的數(shù)據(jù)(單位為mV)作比較。設(shè)計(jì)的架構(gòu)圖如下:
設(shè)計(jì)架構(gòu)圖對應(yīng)端口的功能描述表:
tlc549_Driver模塊采用序列機(jī)實(shí)現(xiàn)接口訪問時(shí)序,并且產(chǎn)生1MHz的ADC_Clk和采集到ADC_data;Control模塊,將采集到的ADC數(shù)據(jù)(ADC_data)換算成對應(yīng)的電壓值,并經(jīng)過二進(jìn)制到BCD轉(zhuǎn)換以后傳送到數(shù)碼管;DIG_LED_DRIVE模塊負(fù)責(zé)數(shù)碼管的驅(qū)動,將傳遞過來的數(shù)據(jù)顯示出來。
設(shè)計(jì)代碼:
tlc549_Driver模塊代碼:
0moduletlc549_Driver(Clk,Rst_n,En,ADC_Din,ADC_Clk,ADC_Cs_n,Data,Get_Flag);
1
2inputClk;//系統(tǒng)50MHz時(shí)鐘輸入
3inputRst_n;//全局復(fù)位
4inputEn;//ADC轉(zhuǎn)換使能,高電平有效
5
6inputADC_Din;//ADC串行數(shù)據(jù)輸入
7
8outputregADC_Clk;//ADC時(shí)鐘信號輸出
9outputregADC_Cs_n;//ADC片選信號輸出
10outputregGet_Flag;//數(shù)據(jù)轉(zhuǎn)換完成標(biāo)志
11outputreg[7:0]Data;//ADC轉(zhuǎn)換以后的電壓值
12
13reg[10:0]Cnt1;//系統(tǒng)時(shí)鐘計(jì)數(shù)器
14reg[7:0]data_tmp;//數(shù)據(jù)寄存器
15
16//系統(tǒng)時(shí)鐘上升沿計(jì)數(shù)
17always@(posedgeClkornegedgeRst_n)
18begin
19if(!Rst_n)
20Cnt1<=11'd0;
21elseif(!En)
22Cnt1<=11'd0;
23elseif(Cnt1==11'd1310)
24Cnt1<=11'd0;
25else
26Cnt1<=Cnt1+1'b1;
27end
28
29always@(posedgeClkornegedgeRst_n)
30begin
31if(!Rst_n)
32begin
33ADC_Clk<=1'b0;
34ADC_Cs_n<=1'b1;
35data_tmp<=8'd0;
36Data<=8'd0;
37end
38elseif(En)
39begin
40case(Cnt1)
411:ADC_Cs_n<=1'b0;//1~71(Tsu)
4271:beginADC_Clk<=1;data_tmp[7]<=ADC_Din;end
4396:ADC_Clk<=0;
44121:beginADC_Clk<=1;data_tmp[6]<=ADC_Din;end
45146:ADC_Clk<=0;
46171:beginADC_Clk<=1;data_tmp[5]<=ADC_Din;end
47196:ADC_Clk<=0;
48221:beginADC_Clk<=1;data_tmp[4]<=ADC_Din;end
49246:ADC_Clk<=0;
50271:beginADC_Clk<=1;data_tmp[3]<=ADC_Din;end
51296:ADC_Clk<=0;
52321:beginADC_Clk<=1;data_tmp[2]<=ADC_Din;end
53346:ADC_Clk<=0;
54371:beginADC_Clk<=1;data_tmp[1]<=ADC_Din;end
55396:ADC_Clk<=0;
56421:beginADC_Clk<=1;data_tmp[0]<=ADC_Din;end
57446:beginADC_Clk<=0;ADC_Cs_n<=1'b1;Get_Flag<=1;end
58447:beginData<=data_tmp;Get_Flag<=0;end//447~1310(Twh)
591310:;
60default:;
61endcase
62end
63else
64begin
65ADC_Cs_n<=1'b1;
66ADC_Clk<=1'b0;
67end
68end
69
70endmodule
Control模塊代碼:
0moduleControl(Clk,Rst_n,Get_Flag,ADC_data,seg_data);
1
2inputClk;//系統(tǒng)時(shí)鐘輸入
3inputRst_n;//系統(tǒng)復(fù)位
4inputGet_Flag;//ADC采集數(shù)據(jù)完成標(biāo)志
5input[7:0]ADC_data;//ADC采集數(shù)據(jù)輸入
6
7outputreg[23:0]seg_data;//數(shù)碼管待顯示數(shù)據(jù)
8
9reg[3:0]qianwei;//千位
10reg[3:0]baiwei;//百位
11reg[3:0]shiwei;//十位
12reg[3:0]gewei;//個(gè)位
13reg[15:0]tenvalue;//采樣的電壓值
14
15//采集電壓值計(jì)算
16always@(posedgeClkornegedgeRst_n)
17begin
18if(!Rst_n)
19tenvalue<=0;
20elseif(Get_Flag)//新的數(shù)據(jù)采集完成,可以進(jìn)行計(jì)算
21tenvalue<=(ADC_data*100*25)/256;
22end
23
24//二進(jìn)制轉(zhuǎn)BCD值
25always@(posedgeClkornegedgeRst_n)
26begin
27if(!Rst_n)
28begin
29qianwei<=0;
30baiwei<=0;
31shiwei<=0;
32gewei<=0;
33end
34else
35begin
36qianwei<=tenvalue/1000;//2
37baiwei<=(tenvalue/100)%10;//5
38shiwei<=(tenvalue/10)%10;//0
39gewei<=tenvalue%10;//0
40end
41end
42
43//數(shù)碼管顯示數(shù)值
44always@(posedgeClkornegedgeRst_n)
45begin
46if(!Rst_n)
47seg_data<=0;
48else
49seg_data<={
50qianwei,//千位
51baiwei,//百位
52shiwei,//十位
53gewei,//個(gè)位
548'hFF//空閑
55};
56end
57
58endmodule
DIG_LED_DRIVE模塊代碼:
0/*數(shù)碼管掃描模塊,位選為外部74hc138譯碼器進(jìn)行控制*/
1/*仿真時(shí)請將本文件設(shè)置為頂層,并在代碼中根據(jù)相應(yīng)注釋中的內(nèi)容選擇cnt1_MAX = 24*/
2
3moduleDIG_LED_DRIVE(Clk,Rst_n,Data,Dig_Led_seg,Dig_Led_sel);
4
5inputClk;//系統(tǒng)時(shí)鐘輸入
6inputRst_n;//系統(tǒng)復(fù)位
7input[23:0]Data;//待顯示數(shù)據(jù)
8
9output[7:0]Dig_Led_seg;//數(shù)碼管段選
10output[2:0]Dig_Led_sel;//數(shù)碼管位選
11
12parametersystem_clk=50_000_000;
13
14// localparam cnt1_MAX = 24;/*仿真的時(shí)候使用,板級驗(yàn)證時(shí)請注釋掉*/
15localparamcnt1_MAX=system_clk/1000/2-1;/*板級驗(yàn)證的時(shí)候使用,仿真時(shí)請注釋掉*/
16
17reg[14:0]cnt1;//分頻計(jì)數(shù)器
18regclk_1K;//掃描時(shí)鐘,1KHz
19reg[2:0]sel_r;//數(shù)碼管位選
20reg[7:0]seg_r;//數(shù)碼管段選
21reg[3:0]disp_data;//單位顯示數(shù)據(jù)緩存
22
23//1KHz時(shí)鐘分頻計(jì)數(shù)器
24always@(posedgeClk)
25begin
26if(!Rst_n)cnt1<=0;
27elseif(cnt1==cnt1_MAX)cnt1<=0;
28elsecnt1<=cnt1+1'b1;
29end
30
31//得到1KHz時(shí)鐘
32always@(posedgeClkornegedgeRst_n)
33begin
34if(!Rst_n)
35clk_1K<=0;
36elseif(cnt1==cnt1_MAX)
37clk_1K<=~clk_1K;
38end
39
40//位選信號控制
41always@(posedgeclk_1KornegedgeRst_n)
42begin
43if(!Rst_n)
44sel_r<=3'd0;
45elseif(sel_r==3'd3)
46sel_r<=3'd0;
47else
48sel_r<=sel_r+1'b1;
49end
50
51//根據(jù)不同的數(shù)碼管位選擇不同的待顯示數(shù)據(jù)
52always@(*)
53begin
54if(!Rst_n)
55disp_data=4'd0;
56else
57begin
58case(sel_r)
593'd0:disp_data=Data[23:20];
603'd1:disp_data=Data[19:16];
613'd2:disp_data=Data[15:12];
623'd3:disp_data=Data[11:8];
633'd4:disp_data=Data[7:4];
643'd5:disp_data=Data[3:0];
65default:disp_data=4'd0;
66endcase
67end
68end
69
70//數(shù)據(jù)譯碼,將待顯示數(shù)據(jù)翻譯為符合數(shù)碼管顯示的編碼
71always@(*)
72begin
73if(!Rst_n)
74seg_r=8'hff;
75else
76begin
77case(disp_data)
784'd0:seg_r=8'hc0;
794'd1:seg_r=8'hf9;
804'd2:seg_r=8'ha4;
814'd3:seg_r=8'hb0;
824'd4:seg_r=8'h99;
834'd5:seg_r=8'h92;
844'd6:seg_r=8'h82;
854'd7:seg_r=8'hf8;
864'd8:seg_r=8'h80;
874'd9:seg_r=8'h90;
884'd10: seg_r=8'h88;
894'd11: seg_r=8'h83;
904'd12: seg_r=8'hc6;
914'd13: seg_r=8'ha1;
924'd14: seg_r=8'h86;
934'd15: seg_r=8'h8e;
94default:seg_r=8'hff;
95endcase
96end
97end
98
99assignDig_Led_seg=seg_r;
100assignDig_Led_sel=sel_r;
101
102endmodule
AD_TLC549頂層模塊代碼:
0moduleAD_TLC549(Clk,Rst_n,ADC_Din,ADC_Clk,ADC_Cs_n,Dig_Led_sel,Dig_Led_seg);
1
2inputClk;
3inputRst_n;
4inputADC_Din;
5
6outputADC_Clk;
7outputADC_Cs_n;
8output[2:0]Dig_Led_sel;
9output[7:0]Dig_Led_seg;
10
11wireGet_Flag;
12wire[7:0]ADC_data;
13wire[23:0]seg_data;
14
15tlc549_Drivertlc549_Driver(
16.Clk(Clk),
17.Rst_n(Rst_n),
18.En(1'b1),
19.ADC_Din(ADC_Din),
20.ADC_Clk(ADC_Clk),
21.ADC_Cs_n(ADC_Cs_n),
22.Data(ADC_data),
23.Get_Flag(Get_Flag)
24);
25
26ControlControl(
27.Clk(Clk),
28.Rst_n(Rst_n),
29.Get_Flag(Get_Flag),
30.ADC_data(ADC_data),
31.seg_data(seg_data)
32);
33
34DIG_LED_DRIVEDIG_LED_DRIVE(
35.Clk(Clk),
36.Rst_n(Rst_n),
37.Data(seg_data),
38.Dig_Led_seg(Dig_Led_seg),
39.Dig_Led_sel(Dig_Led_sel)
40);
41
42endmodule
AD_TLC549_tb頂層測試代碼如下:
0`timescale1ns/1ps
1
2moduleAD_TLC549_tb;
3
4regClk;
5regRst_n;
6regADC_Din;
7
8wireADC_Clk;
9wireADC_Cs_n;
10wire[2:0]Dig_Led_sel;
11wire[7:0]Dig_Led_seg;
12
13initialbegin
14Clk=1;
15Rst_n=0;
16ADC_Din=0;
17#200.1
18Rst_n=1;
19
20#1400ADC_Din=1;//aa
21#1000ADC_Din=0;
22#1000ADC_Din=1;
23#1000ADC_Din=0;
24#1000ADC_Din=1;
25#1000ADC_Din=0;
26#1000ADC_Din=1;
27#1000ADC_Din=0;
28
29#17000
30#1400ADC_Din=1;//98
31#1000ADC_Din=0;
32#1000ADC_Din=0;
33#1000ADC_Din=1;
34#1000ADC_Din=1;
35#1000ADC_Din=0;
36#1000ADC_Din=0;
37#1000ADC_Din=0;
38
39end
40
41AD_TLC549AD_TLC549_dut(
42.Clk(Clk),
43.Rst_n(Rst_n),
44.ADC_Din(ADC_Din),
45.ADC_Clk(ADC_Clk),
46.ADC_Cs_n(ADC_Cs_n),
47.Dig_Led_sel(Dig_Led_sel),
48.Dig_Led_seg(Dig_Led_seg)
49);
50
51always#10Clk=~Clk;
52
53endmodule
仿真圖:
設(shè)計(jì)仿真圖如下所示:
觀察仿真圖,實(shí)現(xiàn)了數(shù)據(jù)的采集,并正確顯示,下板驗(yàn)證結(jié)果也達(dá)到了設(shè)計(jì)的預(yù)期效果。
-
FPGA
+關(guān)注
關(guān)注
1629文章
21754瀏覽量
604221
發(fā)布評論請先 登錄
相關(guān)推薦
評論