• 正文
    • 1.概述
    • 2. 硬件原理
    • 3. 軟件實現(xiàn)
  • 推薦器件
  • 相關推薦
申請入駐 產(chǎn)業(yè)圖譜

FPGA入門基礎之數(shù)碼管顯示

2024/06/01
4812
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

引言:本文介紹數(shù)碼管顯示譯碼基本工作原理及Verilog HDL驅動代碼編寫,進一步熟練掌握FPGA入門基礎知識。

1.概述

數(shù)碼管是顯示屏其中一類,通過對其不同的管腳輸入相對的電流,會使其發(fā)亮,從而顯示出數(shù)字能夠顯示 時間、日期、溫度等所有可用數(shù)字表示的參數(shù)。

由于它的價格便宜,使用簡單,在電器特別是家電領域應用極為廣泛,空調(diào)、熱水器、冰箱等等。絕大多數(shù)熱水器用的都是數(shù)碼管,其他家電也用液晶屏與熒光屏。

2. 硬件原理

如圖2所示,數(shù)碼管按段數(shù)分為七段數(shù)碼管和八段數(shù)碼管,八段數(shù)碼管比七段數(shù)碼管多一個發(fā)光二極管單元(多一個小數(shù)點顯示)。按能顯示多少個“8”可分為1 位、2 位、4 位等等數(shù)碼管。

如圖2所示,按發(fā)光二極管單元連接方式分為共陽極數(shù)碼管和共陰極數(shù)碼管。

圖2:數(shù)碼管共陰極(左側)和共陽極(右側)接法

共陰數(shù)碼管是指將所有發(fā)光二極管的陰極接到一起形成公共陰極(COM)的數(shù)碼管,共陰數(shù)碼管在應用時應將公共極 COM接到地線 GND 上,當某一字段發(fā)光二極管的陽極為高電平時,相應字段就點亮,當某一字段的陽極為低電平時,相應字段就不亮。共陽數(shù)碼管是指將所有發(fā)光二極管的陽極接到一起形成公共陽極(COM)的數(shù)碼管,共陽數(shù)碼管在應用時應將公共極COM 接到+3.3V(高電平),當某一字段發(fā)光二極管的陰極為低電平時,相應字段就點亮,當某一字段的陰極為高電平時,相應字段就不亮。圖3:4位數(shù)碼管共陽極接法

如圖3所示,4位數(shù)碼管的每段全部連接在一起,如果想動態(tài)控制每位數(shù)碼管,就不能將四位數(shù)碼管的COM端連接在一起,必須分別控制每位數(shù)碼管的COM端,即增加位選擇控制信號。8位數(shù)碼管共陽極連接原理圖如圖4所示。

圖4:8位數(shù)碼管原理圖

如圖4所示,8位數(shù)碼管通過Sel[7..0]8個數(shù)據(jù)IO實現(xiàn)位選擇,通過Disp[7..0]8個數(shù)據(jù)IO實現(xiàn)段選擇。由于FPGA IO口驅動電流能力弱,增加三極管可提高驅動能力。如圖4所示,基極為低電平,三極管導通,數(shù)碼管被選中,被選中的數(shù)碼管相應的段發(fā)光顯示。由于4位數(shù)碼管的的數(shù)據(jù)端(ABCDEFG)是公用的,而每一位的數(shù)碼管的公共陽極(COM)是單獨,若某一位數(shù)碼管顯示字符,則這一位的公共陽極就要連接到低電平。

3. 軟件實現(xiàn)

數(shù)碼管顯示有靜態(tài)顯示和動態(tài)顯示兩種方式。

在靜態(tài)顯示中,只考慮段選信號。在不同的時刻,各個位選信號保持不變,并根據(jù)真值表,選擇要顯示的數(shù)字或者字母。由于多位數(shù)碼管段信號是連在一起的,所以這種情況下每位數(shù)碼管顯示的內(nèi)容是想通過的。要想每位數(shù)碼管顯示不同內(nèi)容,只能采用動態(tài)顯示方式。

在動態(tài)顯示中,需要將位選信號考慮進來。在不同的時刻,各個位的位選信號隨時改變,并根據(jù)真值表,選擇顯示不同的數(shù)字或者字母。

3.1 數(shù)碼管靜態(tài)顯示

根據(jù)圖4硬件原理圖,數(shù)碼管位選擇信號為低電平“0”時,同時數(shù)碼管段為低電平“0”時,點亮數(shù)碼管內(nèi)部LED發(fā)光二極管。

數(shù)碼管靜態(tài)顯示代碼如下所示。

/*************************************************數(shù)碼管靜態(tài)顯示按鍵計數(shù)值。*************************************************///位選信號     assign segma_sel_o = 8'h00; //使能所有數(shù)碼管位   //段選信號,關閉DP點顯示  always @(posedge sys_clk_i or negedge rst_n_i) begin         if(!rst_n_i) begin        segma_disp_o  <= 8'b0000001_1;           end  else begin??????case(cnt)?//按鍵計數(shù)值??        4'd0: segma_disp_o  <= 8'b0000001_1; //"0"          4'd1: segma_disp_o  <= 8'b1001111_1; //"1"          4'd2: segma_disp_o  <= 8'b0010010_1; //"2"        4'd3: segma_disp_o  <= 8'b0000110_1; //"3"        4'd4: segma_disp_o  <= 8'b1001100_1; //"4"        4'd5: segma_disp_o  <= 8'b0100100_1; //"5"        4'd6: segma_disp_o  <= 8'b0100000_1; //"6"        4'd7: segma_disp_o  <= 8'b0001111_1; //"7"        4'd8: segma_disp_o  <= 8'b0000000_1; //"8"        4'd9: segma_disp_o  <= 8'b0000100_1; //"9"        4'd10: segma_disp_o <= 8'b0001000_1; //"A"        4'd11: segma_disp_o <= 8'b1100000_1; //"B"        4'd12: segma_disp_o <= 8'b0110001_1; //"C"        4'd13: segma_disp_o <= 8'b1000010_1; //"D"        4'd14: segma_disp_o <= 8'b0110000_1; //"E"        4'd15: segma_disp_o <= 8'b0111000_1; //"F"              endcase       endend

?測試結果如下:

3.2 數(shù)碼管動態(tài)顯示

數(shù)碼管動態(tài)動態(tài)掃描顯示,實際上是利用了兩個現(xiàn)象:人眼的視覺暫留特性和數(shù)碼管的余暉效應。人眼在觀察景物時,光信號傳入到大腦神經(jīng)需要經(jīng)過一段時間,光的作用結束之后我們的視覺影像并不會立刻的消失,這種殘留的視覺被稱為后像,這種現(xiàn)象就被稱為視覺暫留;數(shù)碼管的余暉效應是什么意思呢?當我們停止向發(fā)光二極管供電時,發(fā)光二極管的亮度仍能夠維持一段時間。我們的動態(tài)掃描利用這兩個特性就實現(xiàn)了數(shù)碼管的動態(tài)顯示。

(1)數(shù)碼管位掃描控制代碼:編寫計數(shù)器cnt_scanf,周期性產(chǎn)生數(shù)碼管選擇信號seg_wei_num,根據(jù)seg_wei_num解碼對應的需要使能數(shù)碼管位segma_wei_o。

// 計數(shù)器,控制數(shù)碼管位reg [23:0] cnt_scanf;always @(posedge clk_i or negedge rst_n_i) beginif(!rst_n_i) begin    cnt_scanf <= 24'd0;  endelse begin     if(cnt_scanf == timer_scanf_i)       cnt_scanf <= 24'd0;    else      cnt_scanf <= cnt_scanf + 24'd1;  endend
//數(shù)碼管掃描序號reg [2:0] segma_wei_num; always @(posedge clk_i or negedge rst_n_i) beginif(!rst_n_i) begin    segma_wei_num <= 3'd0;  endelse begin    if(cnt_scanf == timer_scanf_i)      segma_wei_num <= segma_wei_num + 3'd1;    else      segma_wei_num <= segma_wei_num;  endend
//解碼選中的數(shù)碼管always @(posedge clk_i or negedge rst_n_i) beginif(!rst_n_i) begin    segma_wei_o <= 8'b1111_1111;  endelse begin    case(segma_wei_num)      3'd0: segma_wei_o <= 8'b1110_1111; //選中第1個數(shù)碼管      3'd1: segma_wei_o <= 8'b1101_1111; //選中第2個數(shù)碼管      3'd2: segma_wei_o <= 8'b1011_1111; //選中第3個數(shù)碼管      3'd3: segma_wei_o <= 8'b0111_1111; //選中第4個數(shù)碼管          3'd4: segma_wei_o <= 8'b1111_1110; //選中第5個數(shù)碼管      3'd5: segma_wei_o <= 8'b1111_1101; //選中第6個數(shù)碼管      3'd6: segma_wei_o <= 8'b1111_1011; //選中第7個數(shù)碼管      3'd7: segma_wei_o <= 8'b1111_0111; //選中第8個數(shù)碼管       default: segma_wei_o <= 8'b1111_1111;      endcase  endend

(2)數(shù)碼管段顯示控制代碼:根據(jù)當前使能的數(shù)碼管位segma_wei_num,獲取當前數(shù)碼管位需要顯示的數(shù)據(jù)信息led_duan,然后根據(jù)led_duan數(shù)據(jù)解碼映射到需要顯示的每段發(fā)光二極管,數(shù)碼管DP段單獨控制。

//獲取當前數(shù)碼管位DP段always @(*) begin  case(segma_wei_num)    3'd0: segma_duan_o[0] <= i_led0_data[4]; // 第1個數(shù)碼管DP段數(shù)據(jù)    3'd1: segma_duan_o[0] <= i_led1_data[4]; // 第2個數(shù)碼管DP段數(shù)據(jù)        3'd2: segma_duan_o[0] <= i_led2_data[4]; // 第3個數(shù)碼管DP段數(shù)據(jù)    3'd3: segma_duan_o[0] <= i_led3_data[4]; // 第4個數(shù)碼管DP段數(shù)據(jù)        3'd4: segma_duan_o[0] <= i_led4_data[4]; // 第5個數(shù)碼管DP段數(shù)據(jù)    3'd5: segma_duan_o[0] <= i_led5_data[4]; // 第6個數(shù)碼管DP段數(shù)據(jù)        3'd6: segma_duan_o[0] <= i_led6_data[4]; // 第7個數(shù)碼管DP段數(shù)據(jù)    3'd7: segma_duan_o[0] <= i_led7_data[4]; // 第8個數(shù)碼管DP段數(shù)據(jù)      endcaseend
//獲取當前數(shù)碼管位其他段數(shù)據(jù)reg [3:0] led_duan;always @(*) begin  case(segma_wei_num)    3'd0: led_duan <= i_led0_data[3:0]; // 第1個數(shù)碼管其他段數(shù)據(jù)    3'd1: led_duan <= i_led1_data[3:0]; // 第2個數(shù)碼管其他段數(shù)據(jù)        3'd2: led_duan <= i_led2_data[3:0]; // 第3個數(shù)碼管其他段數(shù)據(jù)    3'd3: led_duan <= i_led3_data[3:0]; // 第4個數(shù)碼管其他段數(shù)據(jù)        3'd4: led_duan <= i_led4_data[3:0]; // 第5個數(shù)碼管其他段數(shù)據(jù)    3'd5: led_duan <= i_led5_data[3:0]; // 第6個數(shù)碼管其他段數(shù)據(jù)        3'd6: led_duan <= i_led6_data[3:0]; // 第7個數(shù)碼管其他段數(shù)據(jù)    3'd7: led_duan <= i_led7_data[3:0]; // 第8個數(shù)碼管其他段數(shù)據(jù)      endcaseend
//解碼數(shù)碼管段數(shù)據(jù)always @(*) begin  case(led_duan)      4'd0: segma_duan_o[7:1]  <= 7'b0000001; //"0"       4'd1: segma_duan_o[7:1]  <= 7'b1001111; //"1"      4'd2: segma_duan_o[7:1]  <= 7'b0010010; //"2"      4'd3: segma_duan_o[7:1]  <= 7'b0000110; //"3"      4'd4: segma_duan_o[7:1]  <= 7'b1001100; //"4"      4'd5: segma_duan_o[7:1]  <= 7'b0100100; //"5"      4'd6: segma_duan_o[7:1]  <= 7'b0100000; //"6"      4'd7: segma_duan_o[7:1]  <= 7'b0001111; //"7"      4'd8: segma_duan_o[7:1]  <= 7'b0000000; //"8"      4'd9: segma_duan_o[7:1]  <= 7'b0000100; //"9"      4'd10: segma_duan_o[7:1] <= 7'b0001000; //"A"      4'd11: segma_duan_o[7:1] <= 7'b1100000; //"B"      4'd12: segma_duan_o[7:1] <= 7'b0110001; //"C"      4'd13: segma_duan_o[7:1] <= 7'b1000010; //"D"      4'd14: segma_duan_o[7:1] <= 7'b0110000; //"E"      4'd15: segma_duan_o[7:1] <= 7'b0111000; //"F"      endcaseend

測試結果如下:

歡迎關注FPGA技術實戰(zhàn)公眾號,喜歡就多多轉發(fā)吧!

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風險等級 參考價格 更多信息
XC6SLX9-L1CPG196I 1 AMD Xilinx Field Programmable Gate Array, 715 CLBs, 9152-Cell, CMOS, PBGA196, 8 X 8 MM, 0.50 MM PITCH, LEAD FREE, BGA-196
$204.26 查看
EP2C5T144C8N 1 Altera Corporation Field Programmable Gate Array, 288 CLBs, 402.5MHz, 4608-Cell, CMOS, PQFP144, LEAD FREE, TQFP-144

ECAD模型

下載ECAD模型
$16.36 查看
A3P400-FGG144I 1 Microsemi FPGA & SoC Field Programmable Gate Array, 400000 Gates, CMOS, PBGA144, 1 MM PITCH, GREEN, FBGA-144
$11.75 查看

相關推薦

登錄即可解鎖
  • 海量技術文章
  • 設計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

專注FPGA技術開發(fā),涉及Intel FPGA、Xilinx FPGA技術開發(fā),開發(fā)環(huán)境使用,代碼風格、時序收斂、器件架構以及軟硬件項目實戰(zhàn)開發(fā),個人公眾號:FPGA技術實戰(zhàn)。