0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

FPGA學(xué)習(xí)系列:29. 數(shù)字電壓表設(shè)計(jì)(AD)

FPGA學(xué)習(xí)交流 ? 2018-08-15 14:07 ? 次閱讀

設(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典型的配置電路如下圖所示

image.png

TLC549的端口描述如下:

image.png

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)的控制。

image.png


分析時(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)圖如下:

image.png


設(shè)計(jì)架構(gòu)圖對應(yīng)端口的功能描述表:

image.png


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~71Tsu

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ù)期效果。





聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1629

    文章

    21754

    瀏覽量

    604221
收藏 人收藏

    評論

    相關(guān)推薦

    電壓表的常見故障及排除方法

    。 一、電壓表的基本原理 電壓表的工作原理是利用電壓表內(nèi)部的電阻分壓器將被測電壓降低到可以測量的范圍內(nèi),然后通過指針或數(shù)字顯示的方式顯示測量
    的頭像 發(fā)表于 07-13 10:54 ?3374次閱讀

    電壓表測量電壓是串聯(lián)還是并聯(lián)

    電壓表是一種用于測量電路中兩點(diǎn)之間電壓差的儀器。在測量電壓時(shí),電壓表需要與被測電路連接。根據(jù)連接方式的不同,電壓表可以分為串聯(lián)和并聯(lián)兩種方式
    的頭像 發(fā)表于 07-13 10:46 ?6644次閱讀

    電壓表是根據(jù)什么原理工作的

    分組成: 1.1 測量電路:測量電路是電壓表的核心部分,負(fù)責(zé)將被測電壓轉(zhuǎn)換為電壓表可讀的數(shù)值。測量電路通常由電阻、電容、二極管等元件組成。 1.2 顯示裝置:顯示裝置用于顯示測量結(jié)果。常見的顯示裝置有指針式、
    的頭像 發(fā)表于 07-13 10:44 ?3331次閱讀

    數(shù)字電壓表電路圖 數(shù)字電壓表的工作原理和作用

      數(shù)字電壓表是一種將模擬電壓信號轉(zhuǎn)換為數(shù)字信號并以數(shù)字形式顯示的電子測量儀器。它采用數(shù)字化測量
    的頭像 發(fā)表于 06-27 16:17 ?3319次閱讀
    <b class='flag-5'>數(shù)字</b><b class='flag-5'>電壓表</b>電路圖 <b class='flag-5'>數(shù)字</b><b class='flag-5'>電壓表</b>的工作原理和作用

    源碼系列:基于FPGA數(shù)字電壓表(AD)設(shè)計(jì)

    今天給大俠帶來基于FPGA數(shù)字電壓表設(shè)計(jì),附源碼,獲取源碼,請?jiān)凇?b class='flag-5'>FPGA技術(shù)江湖”公眾號內(nèi)回復(fù)“數(shù)字
    發(fā)表于 05-28 17:29

    數(shù)字電壓表的應(yīng)用場景

    數(shù)字電壓表,作為現(xiàn)代電子測量技術(shù)的重要工具,已經(jīng)廣泛應(yīng)用于各種電氣測量領(lǐng)域。隨著科技的不斷進(jìn)步和應(yīng)用需求的不斷提高,數(shù)字電壓表的功能和性能也在不斷完善,為各行各業(yè)提供了精確、可靠的
    的頭像 發(fā)表于 05-21 17:13 ?875次閱讀

    數(shù)字電壓表的原理與特點(diǎn)

    數(shù)字電壓表(DVM,也稱為數(shù)字多用表或簡稱DMM)是現(xiàn)代電子測量領(lǐng)域中不可或缺的一種測量儀器。與傳統(tǒng)的模擬電壓表相比,數(shù)字
    的頭像 發(fā)表于 05-21 16:54 ?2333次閱讀

    電壓表的讀數(shù)方法 電壓表的讀數(shù)步驟是什么?

    電壓表是一種用于測量電路中兩點(diǎn)之間電壓差的儀器。正確讀取電壓表的讀數(shù)對于確保電路分析和故障診斷的準(zhǔn)確性至關(guān)重要。
    的頭像 發(fā)表于 05-09 16:23 ?4088次閱讀

    電壓表電壓方法 電壓表是如何測量電壓

    電壓表是用來測量電路中兩點(diǎn)之間電壓差的儀器,它在電氣工程、實(shí)驗(yàn)室測試以及日常的電子設(shè)備維護(hù)中扮演著重要角色。
    的頭像 發(fā)表于 05-07 17:16 ?4676次閱讀

    電壓表原理及使用方法 電壓表串聯(lián)在電路中會怎么樣

    電壓表是測量電路中電勢差(電壓)的一種電器儀器。它能夠通過測量兩個(gè)點(diǎn)之間的電勢差來確定電路的電壓。在以下文章中,我們將詳細(xì)介紹電壓表的原理和使用方法,并探討
    的頭像 發(fā)表于 02-02 13:39 ?8655次閱讀

    電壓表的使用方法及注意事項(xiàng) 電壓表的電阻越大越好對嗎

    電壓表是一種用來測量電壓的儀器,在電路實(shí)驗(yàn)和電器維修中起著重要的作用。正確選擇和使用電壓表不僅能提高測量的準(zhǔn)確性,還能確保人身和設(shè)備的安全。以下是電壓表的使用方法及注意事項(xiàng)。 一、
    的頭像 發(fā)表于 02-02 11:13 ?7315次閱讀

    電壓表的使用方法 電壓表的電阻有多大

    電壓表是用來測量電路中電壓的儀器,可以測量直流電壓和交流電壓。使用電壓表需要注意一些注意事項(xiàng),同時(shí)了解
    的頭像 發(fā)表于 02-02 11:05 ?4405次閱讀

    數(shù)字電壓表測量的基本工作原理

    數(shù)字電壓表是一種用于測量電壓的儀器。它基于一些基本的工作原理來實(shí)現(xiàn)測量的準(zhǔn)確性和可靠性。本文將詳細(xì)介紹數(shù)字電壓表的基本工作原理,以及其在測量
    的頭像 發(fā)表于 01-25 13:55 ?1937次閱讀

    數(shù)字電壓表的固有誤差由什么構(gòu)成

    數(shù)字電壓表的固有誤差是指在一定條件下,由于儀器本身存在的不確定因素所導(dǎo)致的測量結(jié)果與待測量真值之間的偏差。數(shù)字電壓表的固有誤差主要由以下幾個(gè)方面構(gòu)成: 量程誤差: 量程誤差是指
    的頭像 發(fā)表于 01-16 15:35 ?1589次閱讀

    數(shù)字電壓表測量的基本工作原理

    數(shù)字電壓表是一種常用的測試儀器,它能夠準(zhǔn)確測量電路中的電壓值。要了解數(shù)字電壓表的工作原理,需要了解它是如何將輸入信號轉(zhuǎn)換為
    的頭像 發(fā)表于 01-11 09:23 ?1475次閱讀