7段數碼管顯示驅動代碼


數碼管顯示進行簡單的介紹,數碼管顯示原理在數電中已經給出了比較詳細的介紹,我就不贅述了,因為我們用的是至芯的開發板,其上的數碼管顯示模塊采用的是共陽極的數碼管,為低電平有效,0-F的顯示碼依次為:

  

數碼管的輸入有3個位選和8個段選給出,位選信號sel來控制哪個數碼管先亮,段選信號seg來控制數碼管顯示什么,位選本來應該是有6個的但是為了節約資源,采用了3-8譯碼器將6根線減少到3根,節約了FPGA的引腳資源。

因為人眼有一個視覺載留,所以60HZ來掃描的時候,數碼管會讓人眼覺得是同時點亮,所以時鍾要大於60hz

下面是具體的代碼實現:

 module scan_led(
    input   wire  clk_1k,
    input   wire  rst_n,
    input   wire  [31:0] d,
    output  wire  [2:0] dig,//sel 
    output  wire  [7:0] seg
  );
  reg [7:0] seg_r;
  reg [2:0] dig_r;
  reg [3:0] disp_dat;
  reg [2:0] count;
  assign dig =dig_r;
  assign seg =sig_r;
  // 時鍾不能直接接全局時鍾,這里的時鍾驅動給的是1k的
  always @(posedge clk_1k or negedge rst_n)
  begin 
   if(!rst_n)
     count <=3'b000;
   else if(count == 3'd5)
     count <=3'b000;
   else 
     count <=count +1'b1;
  end 
 always @(posedge clk_1k or negedge rst_n)
  begin
   case (count)
       3'd0:disp_dat = d[31:28];  
       3'd1:disp_dat = d[27:24];  
       3'd2:disp_dat = d[23:20];  
       3'd3:disp_dat = d[19:16];  
       3'd4:disp_dat = d[15:12];  
       3'd5:disp_dat = d[11:8];      
       3'd6:disp_dat = d[7:4];        
       3'd7:disp_dat = d[3:0];    
   endcase
   case (count)
        3'd0:dig_r = 3'd0;    
        3'd1:dig_r = 3'd1;    
        3'd2:dig_r = 3'd2;    
        3'd3:dig_r = 3'd3;    
        3'd4:dig_r = 3'd4;    
        3'd5:dig_r = 3'd5;    
        3'd6:dig_r = 3'd6;    
        3'd7:dig_r = 3'd7;     
    endcase
  end 
always @(disp_dat)
begin
  case(disp_dat)
       4'h0:seg_r = 8'hc0;
       4'h1:seg_r = 8'hf9;
       4'h2:seg_r = 8'ha4;
       4'h3:seg_r = 8'hb0;
       4'h4:seg_r = 8'h99;
       4'h5:seg_r = 8'h92;
       4'h6:seg_r = 8'h82;
       4'h7:seg_r = 8'hf8;
       4'h8:seg_r = 8'h80;
       4'h9:seg_r = 8'h90;
       4'ha:seg_r = 8'h88;
       4'hb:seg_r = 8'h83;
       4'hc:seg_r = 8'hc6;
       4'hd:seg_r = 8'ha1;
       4'he:seg_r = 8'h86;
       4'hf:seg_r = 8'h8e;  
   endcase  
end 
endmodule

另一種寫法:

 

module display1 (clk, rst_n , sel, seg);    
    input clk;
    input rst_n;
//兩個輸出,位選sel和段選seg
    output reg [2:0] sel;
    output reg [7:0] seg;
//數碼管掃描需要一個慢時鍾 clk_slow,而產生慢時鍾則需要一個計數器 cnt
    reg [15:0] cnt;
    reg clk_slow;
//這個always塊用來產生慢時鍾clk_slow
    always @ (posedge clk)
    begin 
        if(!rst_n)
        begin

            cnt <= 0;
            clk_slow <= 1; //復位時clk_slow靜止不動
        end
        else
        begin
            cnt <= cnt + 1; //復位結束后cnt開始計數
            clk_slow <= cnt[12];  //掃描沒有必要非得是60Hz整,大於60Hz即可
        end
    end
//下面這個always塊用於掃描數碼管,也就是sel循環地變化,
//時鍾每一次上升沿sel變化一次,所以在括號里寫上時鍾上升沿作為觸發條件
    always @ (posedge clk_slow or negedge rst_n)
    begin
        if(!rst_n)
        begin
            sel <= 0;    //復位時sel靜止
        end
        else
        begin
            sel <= sel + 1; //復位后sel開始掃描
            if(sel >= 5)
                sel <= 0;    //因為只有6個數碼管,所以讓sel在0-5之間循環
        end
    end

    always @ (*)
    begin
        if(!rst_n)
            seg <= 8'b11111111;  //按下復位鍵時讓數碼管熄滅,共陽極數碼管0亮1滅
        else
        begin
            case(sel)
            0: seg <= 8'b11111001;   //右起第1個數碼管上顯示1
            1: seg <= 8'b10100100;   //右起第2個數碼管上顯示2
            2: seg <= 8'b10110000;
            3: seg <= 8'b10011001;
            4: seg <= 8'b10010010;
            5: seg <= 8'b10000010;   //右起第6個數碼管上顯示6
            default: seg <= 8'b11111111;
            endcase
        end
    end
endmodule

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM