码迷,mamicode.com
首页 > 其他好文 > 详细

7段数码管显示驱动代码

时间:2016-08-09 02:00:23      阅读:383      评论:0      收藏:0      [点我收藏+]

标签:

数码管显示进行简单的介绍,数码管显示原理在数电中已经给出了比较详细的介绍,我就不赘述了,因为我们用的是至芯的开发板,其上的数码管显示模块采用的是共阳极的数码管,为低电平有效,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 <=3b000;
   else if(count == 3d5)
     count <=3b000;
   else 
     count <=count +1b1;
  end 
 always @(posedge clk_1k or negedge rst_n)
  begin
   case (count)
       3d0:disp_dat = d[31:28];  
       3d1:disp_dat = d[27:24];  
       3d2:disp_dat = d[23:20];  
       3d3:disp_dat = d[19:16];  
       3d4:disp_dat = d[15:12];  
       3d5:disp_dat = d[11:8];      
       3d6:disp_dat = d[7:4];        
       3d7:disp_dat = d[3:0];    
   endcase
   case (count)
        3d0:dig_r = 3d0;    
        3d1:dig_r = 3d1;    
        3d2:dig_r = 3d2;    
        3d3:dig_r = 3d3;    
        3d4:dig_r = 3d4;    
        3d5:dig_r = 3d5;    
        3d6:dig_r = 3d6;    
        3d7:dig_r = 3d7;     
    endcase
  end 
always @(disp_dat)
begin
  case(disp_dat)
       4h0:seg_r = 8hc0;
       4h1:seg_r = 8hf9;
       4h2:seg_r = 8ha4;
       4h3:seg_r = 8hb0;
       4h4:seg_r = 8h99;
       4h5:seg_r = 8h92;
       4h6:seg_r = 8h82;
       4h7:seg_r = 8hf8;
       4h8:seg_r = 8h80;
       4h9:seg_r = 8h90;
       4ha:seg_r = 8h88;
       4hb:seg_r = 8h83;
       4hc:seg_r = 8hc6;
       4hd:seg_r = 8ha1;
       4he:seg_r = 8h86;
       4hf:seg_r = 8h8e;  
   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 <= 8b11111111;  //按下复位键时让数码管熄灭,共阳极数码管0亮1灭
        else
        begin
            case(sel)
            0: seg <= 8b11111001;   //右起第1个数码管上显示1
            1: seg <= 8b10100100;   //右起第2个数码管上显示2
            2: seg <= 8b10110000;
            3: seg <= 8b10011001;
            4: seg <= 8b10010010;
            5: seg <= 8b10000010;   //右起第6个数码管上显示6
            default: seg <= 8b11111111;
            endcase
        end
    end
endmodule

 

7段数码管显示驱动代码

标签:

原文地址:http://www.cnblogs.com/zhouzheng/p/5751557.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!