<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • 小梅哥和你一起深入學習FPGA之數碼管動態掃描

    發布時間:2016-4-13 21:29    發布者:小梅哥
    關鍵詞: FPGA , SOPC , NIOS , 小梅哥 , 芯航線
    電子系統中,通常都需要有輸出設備來輸出或顯示一定的信息,以指示當前系統運行的狀態。在以單片機ARM為主的電子系統中,液晶屏是理想的輸出設備。而FPGA則因為其獨特的硬件結構,如果用RTL電路來驅動彩色液晶屏來顯示一定的數據,勢必是非常不劃算的選擇,而且驅動也極為復雜。數碼管作為一種能夠直觀顯示一定數據信息的輸出設備,具有驅動簡單,顯示直觀的特點,尤其適合作為FPGA系統的輸出設備。本節,小梅哥就將和大家一起進行數碼管驅動的開發。
             
    一、       實驗目的
    實現67段數碼管的驅動,待顯示數據以BCD格式輸入。數碼管刷新時鐘為1KHz。實驗使用了4個獨立按鍵作為輸入,通過按鍵來改變需要數碼管顯示的數據,以驗證數碼管驅動的正確性,同時也可檢驗獨立按鍵消抖模塊的可靠性。
    二、       實驗原理
    數碼管所謂的動態掃描,就是利用人眼的視覺暫留特性,在人眼能分辨的變化速度以外,快速分時的點亮各個數碼管對應的段。因為分別點亮所有數碼管一次所用時間小于人眼的視覺暫留,因此,在人們眼里看來,這些數碼管都是同時持續點亮的,并不會有閃爍的感覺。


    2-1 數碼管實物圖

    關于數碼管的具體原理,請大家網上查閱,小梅哥一個人精力有限,沒辦法在這里從最低層的原理給大家一步一步講起,如果大家有不明白的,請自行百度。這里小梅哥就用最簡單粗暴的方式給大家簡單介紹一下。


    2-2 數碼管簡單等效電路

    上圖為37段數碼管的等效電路圖,在這個圖中,可以明顯的看到24個發光二極管被分為了三組,每一組的8發光二極管正極被接在了一起,通過一個三極管VCC相連。三極管的基極連接到了FPGAIO上,因此,只需要FPGA對應的IO上給出低電平,三極管便會導通。而三組LED中所有的相同編號的LED的負極被連接在了一起,并接到了FPGAIO上。如果我們希望將最左邊一組的led0、led5、led7三個編號的led燈點亮,其它led不亮,則只需要給Q0的基極(sel0)連接上低電平,并將led0、led5、led7的負極(a、f、h)連接上低電平,其它所有端口都輸出高電平,則最左邊一組的對應的三個led燈就會被點亮,而其它led則會處于熄滅狀態。
    假如我們需要在三秒時間內,完成以下三次操作:第一次操作,點亮最左邊一組led燈的led0、led5、led7;第二次操作,點亮中間一組led燈的led1、led2、led3;第三次操作,點亮最右邊一組led燈的led2、led4、led6;那么我們只需要按照如下表格中列出的真值表操作即可:


    按照以上表格,我們就能知道該如何操作了,只需要在不同的時間給各個IO不同的電平,便能實現我們想要的亮滅組合。以上我們是以1秒為單位進行led組的切換的,假如我們將切換速度加快,變為1毫秒一切換,會是什么情況呢?在1毫秒一切換的速度下,完成所有操作所需時間為3ms,遠遠超出了我們人眼所能辨識的變化速度范圍。如果我們讓以上三個操作永遠循環的進行下去,那么我們將看見三組led燈中,我們點亮的那幾個led是同時且一直處于亮著的狀態的,這便是動態掃描的原理,假如我們把每個led做成一個長條型的,并按照如下形狀擺放,便就是我們常見的數碼管了。


    2-3 數碼管段分布

    一、       硬件設計

    2-2只是一個為了講述數碼管原理簡化了的電路模型,常見的數碼管電路結構如下圖所示:



    3-1 數碼管典型電路

             在這個圖中,共有6位數碼管,每個數碼管的正極被接在一個驅動三極管上,三極管的基極連接到三八譯碼器的Y端,則FPGA只需要三個引腳就可最多控制8個數碼管的位選。數碼管的段選在串接了470歐姆的電阻后與FPGAIO相連。這里470歐姆的電阻主要起到限流的作用,保證流過數碼管的電流在正常范圍內。

    一、       架構設計

    本實驗由總共四個模塊組成,分別為數碼管驅動模塊、獨立按鍵檢測模塊、控制模塊和頂層模塊,其架構如下:



    4-1 led實驗模塊組織結構圖

    由圖可知本實驗有1個輸出端口,對應驅動了38譯碼器的三個選擇端和數碼管的8個段選腳。6個輸入端口,對應了4個獨立按鍵輸入和一個時鐘輸入以及一個復位輸入。詳細端口名及其意義如下



    4-1 獨立按鍵檢測實驗端口說明

    因為存在模塊間的連接,因此有部分內部信號,下表為內部信號的名稱和功能說明



    4-2 獨立按鍵檢測實驗內部信號說明



    一、       代碼組織方式

             本實驗中,數碼管的驅動采用了組合邏輯譯碼的方式進行,具體將在代碼解讀時講解。

    實驗中還設計了一個控制器,該控制器主要通過讀取按鍵信息來改變待數碼管待顯示的數據內容。

    按鍵檢測部分使用前一節開發的獨立按鍵的驅動,因此這里不進行過多的分析介紹。


    二、       關鍵代碼解讀

    因為數碼管屬于低速設備,其正常的掃描頻率為500~10KHz,掃描頻率太快,會導致系統功耗增加,顯示效果變暗。掃描頻率太慢,會有明顯的閃爍感。本實驗通過調試觀察,選擇以1KHz作為掃描頻率,實際顯示效果非常好。

    因此本實驗首先就需要產生一個1KHz的掃描時鐘,該時鐘由系統時鐘分頻得到。產生1KHz掃描時鐘的代碼如下:
    • parameter system_clk = 50_000_000;
    • localparam cnt1_MAX = system_clk/1000/2-1;
    • //1KHz時鐘分頻計數器
    •         always@(posedge Clk)
    •         begin
    •                 if(!Rst_n)cnt1<=0;
    •                 else if(cnt1==cnt1_MAX)cnt1<=0;
    •                 else cnt1<=cnt1+1'b1;
    •         end
    •         //得到1KHz時鐘
    •         always@(posedge Clk or negedge Rst_n)
    •         if(!Rst_n)clk_1K<=0;
    •         else if(cnt1==cnt1_MAX)
    •                 clk_1K<=~clk_1K;//翻轉掃描時鐘信號
    •         else ;


    [color=rgb(51, 102, 153) !important]復制代碼

    其中,定義了一個全局參數system_clk,該參數為Clk的頻率,不同的時鐘頻率,只需要更改該參數,就可改變分頻計數器的最大計數值,以保證1KHz分頻的精準性。
    在驅動中,數碼管的位選以掃描時鐘的速率進行切換,因為只有6位數碼管,因此當位選計數到6-1后必須清零從頭開始計數。相關代碼如下:
    //位選信號控制
             always@(posedgeclk_1K or negedge Rst_n)
             if(!Rst_n)sel_r<=3'd0;
             elseif(sel_r == 3'd5)
                       sel_r<=3'd0;
             else
                       sel_r<=sel_r+1'b1;


    每個數碼管需要顯示的內容都不相同,由Data中相應的位指定,Data中各位與數碼管的位對應關系如下:
    因此需要從Data中將每個數碼管被選中時需要顯示的數據提取出來,提取數據的代碼如下所示:
    • //根據不同的數碼管位選擇不同的待顯示數據
    •         always@(*)
    •         if(!Rst_n)
    •                 disp_data=4'd0;
    •         else
    •         begin
    •                 case(sel_r)
    •                         0:disp_data=Data[23:20];
    •                         1:disp_data=Data[19:16];
    •                         2:disp_data=Data[15:12];
    •                         3:disp_data=Data[11:8];
    •                         4:disp_data=Data[7:4];
    •                         5:disp_data=Data[3:0];
    •                         default :disp_data=4'd0;
    •                 endcase
    •         end

    [color=rgb(51, 102, 153) !important]復制代碼


    因為提取出來的數據還是BCD碼的形式,還需要將BCD碼對應的數據翻譯成為數碼管顯示對應字符時應該點亮或熄滅的對應的LED的控制信號,因此必須還有一個BCD碼譯碼的過程,該過程代碼如下所示:
    • //數據譯碼,將待顯示數據翻譯為符合數碼管顯示的編碼
    •         always@(*)
    •         if(!Rst_n)
    •                 seg_r=8'hff;
    •         else
    •         begin
    •                 case(disp_data)
    •                         4'd0:        seg_r=8'hc0;
    •                         4'd1:        seg_r=8'hf9;
    •                         4'd2:        seg_r=8'ha4;
    •                         4'd3:        seg_r=8'hb0;
    •                         4'd4:        seg_r=8'h99;
    •                         4'd5:        seg_r=8'h92;
    •                         4'd6:        seg_r=8'h82;
    •                         4'd7:        seg_r=8'hf8;
    •                         4'd8:        seg_r=8'h80;
    •                         4'd9:        seg_r=8'h90;
    •                         4'd10:        seg_r=8'h88;
    •                         4'd11:        seg_r=8'h83;
    •                         4'd12:        seg_r=8'hc6;
    •                         4'd13:        seg_r=8'ha1;
    •                         4'd14:        seg_r=8'h86;
    •                         4'd15:        seg_r=8'h8e;
    •                         default : seg_r=8'hff;
    •                 endcase
    •         end


    [color=rgb(51, 102, 153) !important]復制代碼

    最后,需要將位選和段選信號輸出:
             assignDig_Led_seg = seg_r;
             assignDig_Led_sel = sel_r;

    控制部分相對簡單,只需要根據對應的 按鍵信息,給待顯示的數據加上一個對應的值,該部分代碼如下所示:
    always @(posedge Clk or negedge Rst_n)
             if(!Rst_n)
                       Dig_Led_Data<= 24'd0;
             elseif(Key_Flag)
             begin         
                       case(Key_Value)
                                4'b0001: Dig_Led_Data<= Dig_Led_Data + 23'd1;
                                4'b0010: Dig_Led_Data<= Dig_Led_Data + 23'd100;
                                4'b0100: Dig_Led_Data<= Dig_Led_Data + 23'd10000;
                                4'b1000: Dig_Led_Data<= Dig_Led_Data + 23'd100000;
                                default: Dig_Led_Data<= Dig_Led_Data;
                       endcase
             end


    一、       測試平臺設計

    本實驗主要對數碼管驅動引腳的狀態與預期進行比較和分析,通過仿真,驗證設計的正確性和合理性。數碼管驅動模塊的testbench如下所示:

    `timescale 1ns/1ns
    module DIG_LED_DRIVE_tb;
             reg [23:0]data;
             reg clk;
             reg rst_n;
             wire [7:0]seg;
             wire [2:0]sel;
             
             DIG_LED_DRIVE DIG_LED_DRIVE_inst1(
                       .Data(data),
                       .Clk(clk),
                       .Rst_n(rst_n),
                       .Dig_Led_seg(seg),
                       .Dig_Led_sel(sel)
             );
             initial begin
                       data = 0;
                       clk = 1;
                       rst_n = 0;
                       #200;
                       rst_n = 1;
                       data = 24'h012345;
                       #10000;
                       data = 24'h518918;
                       #10000;
                       data = 24'h543210;
                       #10000;
                       $stop;      
             end
             
             always #10 clk = ~clk;
    endmodule


    每隔一段時間,更換數碼管的Data輸入數據,觀察數碼管的輸出是否正確。


    一、       仿真分析



    如有任何疑問,歡迎加入芯航線FPGA學習支持群(472607506)進行討論
    本文地址:http://www.portaltwn.com/thread-165251-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • Dev Tool Bits——使用MPLAB® Discover瀏覽資源
    • Dev Tool Bits——使用條件軟件斷點宏來節省時間和空間
    • Dev Tool Bits——使用DVRT協議查看項目中的數據
    • Dev Tool Bits——使用MPLAB® Data Visualizer進行功率監視
    • 貿澤電子(Mouser)專區

    相關視頻

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷