精华内容
下载资源
问答
  • 数码管动态显示

    2019-10-05 14:17:16
    数码管显示分为静态显示和动态显示。静态显示没什么卵用,和led灯没差别。而动态显示用处很大,基本上数码管的使用都是动态显示。其原理很简单:视觉暂留效应。数码管从右到左,一个接... 第一种数码管动态显示:采...

      数码管显示分为静态显示和动态显示。静态显示没什么卵用,和led灯没差别。而动态显示用处很大,基本上数码管的使用都是动态显示。其原理很简单:视觉暂留效应。数码管从右到左,一个接一个的亮起熄灭,让其总的速度加快,人眼看上去就像是一直亮着一样。扫描时间间隔建议为20ms以内,人眼才不会感到闪烁。一般来说一位数码管扫描1ms就能得到不错的效果了。

    一、方法1

      第一种数码管动态显示:采用分频时钟扫描方法

      1 //======================================================================
      2 // --- 名称 : seg_display
      3 // --- 作者 : xianyu_FPGA
      4 // --- 日期 : 2018-11-10
      5 // --- 描述 : 数码管动态显示模块,改自小梅哥FPGA
      6 //======================================================================
      7 
      8 module seg_display
      9 //---------------------<端口声明>---------------------------------------
     10 (
     11 input                   clk                 , //时钟,50Mhz
     12 input                   rst_n               , //复位,低电平有效
     13 input                   en                  , //数码管显示使能
     14 input      [31:0]       data                , //输入数据
     15 output     [ 7:0]       seg_sel             , //数码管位选
     16 output reg [ 7:0]       seg_data              //数码管段选,即内容显示
     17 );
     18 //---------------------<信号定义>---------------------------------------
     19 reg  [14:0]             cnt                 ;
     20 wire                    add_cnt             ;
     21 wire                    end_cnt             ;
     22 reg                     clk_1k              ;
     23 reg  [ 7:0]             seg_sel_r           ;
     24 reg  [ 3:0]             data_tmp            ;
     25 
     26 //----------------------------------------------------------------------
     27 //--   1k分频,扫描一个数目管时间为1ms
     28 //----------------------------------------------------------------------
     29 
     30 //计数
     31 always @(posedge clk or negedge rst_n)begin
     32     if(!rst_n)
     33         cnt <= 0;
     34     else if(add_cnt)begin
     35         if(end_cnt)
     36             cnt <= 0;
     37         else
     38             cnt <= cnt + 1;
     39     end
     40     else
     41         cnt <= cnt;
     42 end
     43 
     44 assign add_cnt = en;    //en为1才允许计数
     45 assign end_cnt = add_cnt && cnt==25000-1;
     46 
     47 //分频
     48 always @(posedge clk or negedge rst_n)begin
     49     if(!rst_n)
     50         clk_1k <= 0;
     51     else if(end_cnt)
     52         clk_1k <= ~clk_1k;
     53     else
     54         clk_1k <= clk_1k;
     55 end
     56 
     57 //----------------------------------------------------------------------
     58 //--   数码管扫描,8位循环扫描,频率为1k
     59 //----------------------------------------------------------------------
     60 always @(posedge clk_1k or negedge rst_n)begin
     61     if(!rst_n)
     62         seg_sel_r <= 8'b0000_0001;
     63     else if(seg_sel==8'b1000_0000)
     64         seg_sel_r <= 8'b0000_0001;
     65     else
     66         seg_sel_r <= seg_sel << 1;
     67 end
     68 
     69 //----------------------------------------------------------------------
     70 //--   位选,不同计数对应不同位选编码,也对应分割的不同数据
     71 //----------------------------------------------------------------------
     72 always @(*)begin
     73     case(seg_sel_r)
     74         8'b0000_0001: data_tmp = data[ 3: 0] ; // 位1
     75         8'b0000_0010: data_tmp = data[ 7: 4] ; // 位2
     76         8'b0000_0100: data_tmp = data[11: 8] ; // 位3
     77         8'b0000_1000: data_tmp = data[15:12] ; // 位4
     78         8'b0001_0000: data_tmp = data[19:16] ; // 位5
     79         8'b0010_0000: data_tmp = data[23:20] ; // 位6
     80         8'b0100_0000: data_tmp = data[27:24] ; // 位7
     81         8'b1000_0000: data_tmp = data[31:28] ; // 位8
     82         default:       data_tmp = 4'b0000     ;
     83     endcase
     84 end
     85 
     86 assign seg_sel = en ? seg_sel_r : 8'b0000_0000; // 位选使能
     87 
     88 //----------------------------------------------------------------------
     89 //--   段选,将不同分割数据进行段选编码
     90 //----------------------------------------------------------------------
     91 always @(*)begin
     92     case(data_tmp)
     93         4'h0:   seg_data = 8'b1100_0000;
     94         4'h1:   seg_data = 8'b1111_1001;
     95         4'h2:   seg_data = 8'b1010_0100;
     96         4'h3:   seg_data = 8'b1011_0000;
     97         4'h4:   seg_data = 8'b1001_1001;
     98         4'h5:   seg_data = 8'b1001_0010;
     99         4'h6:   seg_data = 8'b1000_0010;
    100         4'h7:   seg_data = 8'b1111_1000;
    101         4'h8:   seg_data = 8'b1000_0000;
    102         4'h9:   seg_data = 8'b1001_0000;
    103         4'ha:   seg_data = 8'b1000_1000;
    104         4'hb:   seg_data = 8'b1000_0011;
    105         4'hc:   seg_data = 8'b1100_0110;
    106         4'hd:   seg_data = 8'b1010_0001;
    107         4'he:   seg_data = 8'b1000_0110;
    108         4'hf:   seg_data = 8'b1011_1111;
    109         default:seg_data = 8'b1111_1111;
    110     endcase
    111 end
    112 
    113 
    114 endmodule

     

    二、方法2

      第二种数码管动态显示方法:采用直接计数扫描方法

      1 //======================================================================
      2 // --- 名称 : seg_display
      3 // --- 作者 : xianyu_FPGA
      4 // --- 日期 : 2018-11-10
      5 // --- 描述 : 数码管动态显示模块
      6 //======================================================================
      7 
      8 module seg_display
      9 //---------------------<参数定义>---------------------------------------
     10 #(
     11 parameter SEG_SEL       = 8                 , //数码管位数:8
     12 parameter SEG_DATA      = 8                 , //数码管段数:8
     13 parameter TIME_1MS      = 50000             , //1ms时间
     14 parameter TIME_1MS_W    = 16                  //1ms时间位宽
     15 )
     16 //---------------------<端口声明>---------------------------------------
     17 (
     18 input                       clk             , //时钟,50Mhz
     19 input                       rst_n           , //复位,低电平有效
     20 input                       en              , //数码管显示使能
     21 input      [SEG_SEL*4-1:0]  data            , //输入数据
     22 output     [SEG_SEL  -1:0]  seg_sel         , //数码管位选
     23 output reg [SEG_DATA -1:0]  seg_data          //数码管段选,即内容显示
     24 );
     25 //---------------------<信号定义>---------------------------------------
     26 reg  [TIME_1MS_W-1:0]   cnt0                ;
     27 wire                    add_cnt0            ;
     28 wire                    end_cnt0            ;
     29 reg  [2:0]              cnt1                ;
     30 wire                    add_cnt1            ;
     31 wire                    end_cnt1            ;
     32 reg  [3:0]              data_tmp            ;
     33 reg  [SEG_SEL-1:0]      seg_sel_r           ;
     34 
     35 //----------------------------------------------------------------------
     36 //--   1个数码管亮1ms
     37 //----------------------------------------------------------------------
     38 always @(posedge clk or negedge rst_n)begin
     39     if(!rst_n)
     40         cnt0 <= 0;
     41     else if(add_cnt0)begin
     42         if(end_cnt0)
     43             cnt0 <= 0;
     44         else
     45             cnt0 <= cnt0 + 1;
     46     end
     47     else
     48         cnt0 <= cnt0;
     49 end
     50 
     51 assign add_cnt0 = en; // 使能有效才计数
     52 assign end_cnt0 = add_cnt0 && cnt0==TIME_1MS-1;
     53 
     54 //----------------------------------------------------------------------
     55 //--   对各位数码管不断扫描
     56 //----------------------------------------------------------------------
     57 always @(posedge clk or negedge rst_n)begin 
     58     if(!rst_n)
     59         cnt1 <= 0;
     60     else if(add_cnt1)begin
     61         if(end_cnt1)
     62             cnt1 <= 0;
     63         else
     64             cnt1 <= cnt1 + 1;
     65     end
     66     else
     67         cnt1 <= cnt1;
     68 end
     69 
     70 assign add_cnt1 = end_cnt0;
     71 assign end_cnt1 = add_cnt1 && cnt1==SEG_SEL-1;
     72 
     73 //----------------------------------------------------------------------
     74 //--   位选,不同计数对应不同位选编码,也对应分割的不同数据
     75 //----------------------------------------------------------------------
     76 always @(*)begin
     77     case(cnt1)
     78       3'd0  : begin seg_sel_r = 8'b0000_0001; data_tmp = data[ 3: 0]; end // 位1
     79       3'd1  : begin seg_sel_r = 8'b0000_0010; data_tmp = data[ 7: 4]; end // 位2
     80       3'd2  : begin seg_sel_r = 8'b0000_0100; data_tmp = data[11: 8]; end // 位3
     81       3'd3  : begin seg_sel_r = 8'b0000_1000; data_tmp = data[15:12]; end // 位4
     82       3'd4  : begin seg_sel_r = 8'b0001_0000; data_tmp = data[19:16]; end // 位5
     83       3'd5  : begin seg_sel_r = 8'b0010_0000; data_tmp = data[23:20]; end // 位6
     84       3'd6  : begin seg_sel_r = 8'b0100_0000; data_tmp = data[27:24]; end // 位7
     85       3'd7  : begin seg_sel_r = 8'b1000_0000; data_tmp = data[31:28]; end // 位8
     86     default : begin seg_sel_r = 8'b0000_0000; data_tmp = 4'b0000;     end
     87     endcase
     88 end
     89 
     90 assign seg_sel = en ? seg_sel_r : 8'b0000_0000; // 位选使能
     91 
     92 //----------------------------------------------------------------------
     93 //--   段选,将不同分割数据进行段选编码
     94 //----------------------------------------------------------------------
     95 always @(*)begin
     96     case(data_tmp)
     97         4'h0:   seg_data = 8'b1100_0000;
     98         4'h1:   seg_data = 8'b1111_1001;
     99         4'h2:   seg_data = 8'b1010_0100;
    100         4'h3:   seg_data = 8'b1011_0000;
    101         4'h4:   seg_data = 8'b1001_1001;
    102         4'h5:   seg_data = 8'b1001_0010;
    103         4'h6:   seg_data = 8'b1000_0010;
    104         4'h7:   seg_data = 8'b1111_1000;
    105         4'h8:   seg_data = 8'b1000_0000;
    106         4'h9:   seg_data = 8'b1001_0000;
    107         4'ha:   seg_data = 8'b1000_1000;
    108         4'hb:   seg_data = 8'b1000_0011;
    109         4'hc:   seg_data = 8'b1100_0110;
    110         4'hd:   seg_data = 8'b1010_0001;
    111         4'he:   seg_data = 8'b1000_0110;
    112         4'hf:   seg_data = 8'b1000_1110;
    113         default:seg_data = 8'b1111_1111;
    114     endcase
    115 end
    116 
    117 
    118 endmodule
    119 
    120 /*
    121 //----------------------------------------------------------------------
    122 //--   位选这样写也行,代码变得很秀
    123 //----------------------------------------------------------------------
    124 always @(posedge clk or negedge rst_n)begin
    125     if(!rst_n)
    126         seg_sel <= {SEG_SEL{1'b0};
    127     else if(en)
    128         seg_sel <= ~(1'b1<<cnt1);
    129     else
    130         seg_sel <= {SEG_SEL{1'b0};
    131 end
    132 
    133 always  @(*)begin
    134     data_tmp = data[(cnt1+1)*4-1 -:4];
    135 end
    136 
    137 */

     

      以上两种方法实测均有效,数码管足够亮且不闪烁不重影,以后使用时可以直接拿来当数码管的显示模块。使用时要注意你的数码管器件的位数是几位?段数是7段还是8段?低电平有效还是高电平有效?接口是直接连接还是通过HC595芯片连接?这几个问题搞清楚了,数码管显示也就不是问题了。

     

    三、HC595

      附上小梅哥FPGA的HC595模块的代码,可以直接搭配数码管动态显示模块使用,在顶层例化连接一下就行了。

      1 //======================================================================
      2 // --- 名称 : HC595
      3 // --- 作者 : xianyu_FPGA
      4 // --- 日期 : 2018-11-10
      5 // --- 描述 : HC595驱动
      6 //======================================================================
      7 
      8 module HC595
      9 //---------------------<参数定义>---------------------------------------
     10 #(
     11 parameter SEG_SEL       = 8                 , //8位
     12 parameter SEG_DATA      = 8                   //8段
     13 )
     14 //---------------------<端口声明>---------------------------------------
     15 (
     16 input                   clk                 , //时钟,50Mhz
     17 input                   rst_n               , //复位,低电平有效
     18 input                   en                  , //数码管使能信号
     19 input  [SEG_SEL -1:0]   seg_sel             , //数码管位选
     20 input  [SEG_DATA-1:0]   seg_data            , //数码管段选
     21 output reg              ST_CP               , //存储寄存器时钟输出
     22 output reg              SH_CP               , //移位寄存器时钟输出
     23 output reg              DS                    //串行数据输入
     24 );
     25 //---------------------<信号定义>---------------------------------------
     26 reg  [ 1:0]             cnt0                ;
     27 wire                    add_cnt0            ;
     28 wire                    end_cnt0            ;
     29 reg  [ 5:0]             cnt1                ;
     30 wire                    add_cnt1            ;
     31 wire                    end_cnt1            ;
     32 wire                    sclk                ; //分频时钟信号
     33 wire [ 5:0]             sclk_cnt            ; //序列机计数器
     34 
     35 //----------------------------------------------------------------------
     36 //--   4分频计数器
     37 //----------------------------------------------------------------------
     38 always @(posedge clk or negedge rst_n)begin
     39     if(!rst_n)
     40         cnt0 <= 0;
     41     else if(add_cnt0)begin
     42         if(end_cnt0)
     43             cnt0 <= 0;
     44         else
     45             cnt0 <= cnt0 + 1;
     46     end
     47     else
     48         cnt0 <= cnt0;
     49 end
     50 
     51 assign add_cnt0 = en;
     52 assign end_cnt0 = add_cnt0 && cnt0==4-1;
     53 
     54 assign sclk = end_cnt0;
     55 
     56 //----------------------------------------------------------------------
     57 //--   序列机计数器
     58 //----------------------------------------------------------------------
     59 always @(posedge clk or negedge rst_n)begin 
     60     if(!rst_n)
     61         cnt1 <= 0;
     62     else if(add_cnt1)begin
     63         if(end_cnt1)
     64             cnt1 <= 0;
     65         else
     66             cnt1 <= cnt1 + 1;
     67     end
     68     else
     69         cnt1 <= cnt1;
     70 end
     71 
     72 assign add_cnt1 = sclk;
     73 assign end_cnt1 = add_cnt1 && cnt1==35-1;
     74 
     75 assign sclk_cnt = cnt1;
     76 
     77 //-------------------------------------------------------------------------------
     78 //--   SHCP:移位寄存器的时钟输入,上升沿时移位寄存器中的数据依次移动一位
     79 //--   STCP:存储寄存器的时钟输入,上升沿时移位寄存器中的数据进入存储寄存器
     80 //--   通常STCP置为低电平,移位结束后再在ST_CP端产生一个正脉冲更新显示数据
     81 //-------------------------------------------------------------------------------
     82 always @(posedge clk or negedge rst_n)begin
     83     if(!rst_n)begin
     84         ST_CP <= 0;
     85         SH_CP <= 0;
     86         DS    <= 0;
     87     end 
     88     else begin
     89         case(sclk_cnt)
     90              0: begin             SH_CP <= 0;                    end 
     91              1: begin ST_CP <= 0; SH_CP <= 1;                    end 
     92              2: begin             SH_CP <= 0; DS <= seg_data[7]; end
     93              3: begin             SH_CP <= 1;                    end
     94              4: begin             SH_CP <= 0; DS <= seg_data[6]; end
     95              5: begin             SH_CP <= 1;                    end
     96              6: begin             SH_CP <= 0; DS <= seg_data[5]; end
     97              7: begin             SH_CP <= 1;                    end
     98              8: begin             SH_CP <= 0; DS <= seg_data[4]; end
     99              9: begin             SH_CP <= 1;                    end
    100             10: begin             SH_CP <= 0; DS <= seg_data[3]; end
    101             11: begin             SH_CP <= 1;                    end
    102             12: begin             SH_CP <= 0; DS <= seg_data[2]; end
    103             13: begin             SH_CP <= 1;                    end
    104             14: begin             SH_CP <= 0; DS <= seg_data[1]; end
    105             15: begin             SH_CP <= 1;                    end
    106             16: begin             SH_CP <= 0; DS <= seg_data[0]; end
    107             17: begin             SH_CP <= 1;                    end
    108             18: begin             SH_CP <= 0; DS <= seg_sel[7];  end
    109             19: begin             SH_CP <= 1;                    end
    110             20: begin             SH_CP <= 0; DS <= seg_sel[6];  end
    111             21: begin             SH_CP <= 1;                    end
    112             22: begin             SH_CP <= 0; DS <= seg_sel[5];  end
    113             23: begin             SH_CP <= 1;                    end
    114             24: begin             SH_CP <= 0; DS <= seg_sel[4];  end
    115             25: begin             SH_CP <= 1;                    end
    116             26: begin             SH_CP <= 0; DS <= seg_sel[3];  end
    117             27: begin             SH_CP <= 1;                    end
    118             28: begin             SH_CP <= 0; DS <= seg_sel[2];  end
    119             29: begin             SH_CP <= 1;                    end
    120             30: begin             SH_CP <= 0; DS <= seg_sel[1];  end
    121             31: begin             SH_CP <= 1;                    end
    122             32: begin             SH_CP <= 0; DS <= seg_sel[0];  end
    123             33: begin             SH_CP <= 1;                    end
    124             34: begin ST_CP <= 1;                                end
    125             default:
    126                 begin ST_CP <= 0; SH_CP <= 0; DS <= 0          ; end
    127         endcase
    128     end
    129 end
    130 
    131 endmodule

     

      ok,数码管的学习就到这里,以后遇到问题再补充进来。

     

    参考资料:

    [1]小梅哥FPGA教程

    [2]锆石科技FPGA教程

    转载于:https://www.cnblogs.com/xianyufpga/p/11006321.html

    展开全文
  • 本文主要讲了单片机数码管动态显示原理,下面一起来学习一下
  • 单片机数码管动态显示
  • 单片机数码管动态显示程序实验,数码管显示一般分静态显示及动态显示两种驱动方式,静态显示占用口线比较多,本文介绍的是如何实现数码管动态显示,应该说数码管动态显示是单片机外部指令输出的重要途径,因此如何...
  • 数码管动态显示模块

    2021-04-09 17:18:55
    为什么要学习数码管动态显示 多个数码管的段选是连在一起的(如果不连在一起就会占用大量的I/O资源),所以需要快速刷新来保证所有的数码管都亮,并且也可以用数码管来显示结果. 数码管为共阳极,即给端口低电平...

    为什么要学习数码管动态显示

    • 多个数码管的段选是连在一起的(如果不连在一起就会占用大量的I/O资源),所以需要快速刷新来保证所有的数码管都亮,并且也可以用数码管来显示结果.
    • 数码管为共阳极,即给端口低电平才能点亮

    数码管显示代码

    module seg_dynamic(
    	input						sys_clk		,
    	input						sys_rst_n	,
    	input			[19:0] 		data		, 	//输入的数据
    	input			[5:0]		point		,	//小数点位,高电平使能
    	input						seg_en		,	//数码管使能,高电平有效
    	input						sign		,	//符号位,高电平有效
    	
    	output reg 		[5:0]		sel			,
    	output reg 		[7:0]		seg
    	
    );
    
    //parameter define
    parameter CNT_1MS = 16'd50_000 - 1'd1;
    
    //reg define
    reg   [15:0]	cnt_1ms		;
    reg				flag_1ms	;
    reg   [4:0 ]	display		;
    reg	  [23:0]	data_reg	;
    
    //wire define
    wire	[3:0] 	unit		;
    wire	[3:0] 	ten			;
    wire	[3:0] 	hun			;
    wire	[3:0] 	tho			;
    wire	[3:0] 	t_tho		;
    wire	[3:0] 	h_tho		;
    
    //二进制转BCD码
    assign unit  = data % 4'd10 				;		//个位数
    assign ten   = data / 4'd10 % 4'd10 		;		//十位数
    assign hun   = data / 7'd100 % 4'd10 		;		//百位数
    assign tho   = data / 10'd1000% 4'd10 		;		//千位数
    assign t_tho = data / 14'd10000% 4'd10 		;		//万位数
    assign h_tho = data / 17'd100000 			;		//十万位数
    
    //data_reg:用于处理输入的数据,进而根据数据来分配数码管
    always @ (posedge sys_clk or negedge sys_rst_n) begin
    	if(!sys_rst_n)
    		data_reg <= 24'd0;
    	else	if(h_tho || point[5])	//十万位不为零或者最高位有小数点
    		data_reg <= {h_tho,t_tho,tho,hun,ten,unit};
    	else  if((t_tho || point[4]) && (sign == 1'b1)) //万位不为零或者第4位有小数点且有符号
    		data_reg <= {4'd10,t_tho,tho,hun,ten,unit};
    	else 	if((t_tho || point[4]) && (sign == 1'b0)) //万位不为零或者第4位有小数点且没有符号
    		data_reg <= {4'd11,t_tho,tho,hun,ten,unit};
    	else  if((tho || point[3]) && (sign == 1'b1))	//千位不为零或者第4位有小数点且有符号
    		data_reg <= {4'd11,4'd10,tho,hun,ten,unit};
    	else  if((tho || point[3]) && (sign == 1'b0))	//千位不为零或者第4位有小数点且没有符号	
    		data_reg <= {4'd11,4'd11,tho,hun,ten,unit};
    	else	if((hun || point[2]) && (sign == 1'b1))	//百位不为零或者第4位有小数点且有符号
    		data_reg <= {4'd11,4'd11,4'd10,hun,ten,unit};
    	else	if((hun || point[2]) && (sign == 1'b0))	//百位不为零或者第4位有小数点且没有符号
    		data_reg <= {4'd11,4'd11,4'd11,hun,ten,unit};		
    	else	if((ten || point[1]) && (sign == 1'b1))	//十位不为零或者第4位有小数点且有符号
    		data_reg <= {4'd11,4'd11,4'd11,4'd10,ten,unit};
    	else	if((ten || point[1]) && (sign == 1'b0))	//十位不为零或者第4位有小数点且没有符号
    		data_reg <= {4'd11,4'd11,4'd11,4'd11,ten,unit};		
    	else	if((unit || point[0]) && (sign == 1'b1))	//个位不为零或者第4位有小数点且有符号
    		data_reg <= {4'd11,4'd11,4'd11,4'd11,4'd10,unit};		
    	else
    		data_reg <= {4'd11,4'd11,4'd11,4'd11,4'd11,unit};			
    end	
    			
    //cnt_1ms:从0计数到1ms的计数器
    always @ (posedge sys_clk or negedge sys_rst_n) begin
    	if(!sys_rst_n)
    		cnt_1ms <=	16'd0;
    	else if(cnt_1ms == CNT_1MS)
    		cnt_1ms <=	16'd0;
    	else
    		cnt_1ms <= cnt_1ms + 1'd1;
    end
    
    //flag_1ms :当cnt_1ms计数到CNT_1MS,产生一个时钟周期的高电平
    always @ (posedge sys_clk or negedge sys_rst_n) begin
    	if(!sys_rst_n)
    		flag_1ms <= 1'b0;
    	else if(cnt_1ms == CNT_1MS -1'b1)
    		flag_1ms <= 1'b1;
    	else
    		flag_1ms <= 1'b0;		
    end
    
    //sel:位选信号,用于数码管的快速刷新
    always @ (posedge sys_clk or negedge sys_rst_n) begin
    	if(!sys_rst_n)
    		sel <= 6'b111_110;
    	else	if(flag_1ms == 1'b1)
    		sel <= {sel[4:0],sel[5]};
    	else
    		sel <= sel;
    end
    
    //display:根据位选来对段选的数据进行控制
    always @ (posedge sys_clk or negedge sys_rst_n) begin
    	if(!sys_rst_n)
    		display <= 4'd0;
    	else
    		case (sel)
    			6'b111_110	:	display	<=	data_reg	[3:0]			;
    			6'b111_101	:	display	<=	data_reg	[7:4]			;
    			6'b111_011	:	display	<=	data_reg	[11:8]			;	
    			6'b110_111	:	display	<=	data_reg	[15:12]			;	
    			6'b101_111	:	display	<=	data_reg	[19:16]			;	
    			6'b011_111	:	display	<=	data_reg	[23:20]			;	
    			default		:	display	<=	4'd0						;	
    		endcase
    end
    
    //seg:位选信号,用于显示一位数码管上的数字
    always @ (posedge sys_clk or negedge sys_rst_n) begin
    	if(!sys_rst_n)
    		seg <= 8'b11_111_111;
    	else
    		case (display)
    			4'd0		:	seg	 <= 	8'hc0				;	
    			4'd1		:	seg	 <= 	8'hf9				;
    			4'd2		:	seg	 <= 	8'ha4				;
    			4'd3		:	seg	 <= 	8'hb0				;
    			4'd4		:	seg	 <= 	8'h99				;
    			4'd5		:	seg	 <= 	8'h92				;
    			4'd6		:	seg	 <= 	8'h82				;
    			4'd7		:	seg	 <= 	8'hf8				;
    			4'd8		:	seg	 <= 	8'h80				;
    			4'd9		:	seg	 <= 	8'h90				;
    			4'd10		:	seg	 <= 	8'b1011_1111		;		//代表负号
    			4'd11		:	seg	 <= 	8'hff				;		//不显示
    			default		:	seg	 <=   	8'hff				;	
    			endcase	
    end
    
    
    endmodule
    
    展开全文
  • 说明: 驱动四位一体数码管动态显示数字,可方便的移植到其它程序中。 例如:1、硬件改为三位一体或二位一体数码管,只需修改Display_Scan()函数COM个数。 2、本例中,采用了共阴数码管,如果用在共阳数码管,只...
  • 数码管动态显示6个设定数 参照51单片机郭天祥教程
  • MAX7221控制数码管动态显示,MAX7221是集成式共阴极数码管驱动芯片,对于学习数码管驱动的同学可以提供很大的帮助
  • 在单片机开发板上,通过单片机控制数码管动态显示5201314,并闪烁显示
  • 名称:定时器控制数码管动态显示 说明:8 个数码管上分两组动态显示年月日与时分秒,本例的位显示延时用定时器实现。
  • MAX7221控制数码管动态显示,,比赛练习案例,仿真实例,现成调用封装使用,可运行的仿真电路图和调好的程序,开箱即用。适用于教学案例、毕业设计、电子设计比赛、出书项目实例,实际设计、个人DIY参考。 已调试好...
  • STM8基于74HC595串行数码管动态显示
  • 电子-STM32数码管动态显示.zip,单片机/嵌入式STM32-F0/F1/F2
  • 21\\_实战篇\\_数码管动态显示ppt,21_实战篇_数码管动态显示
  • 51单片机_数码管动态显示_数码管鬼影_数码管消影 ## 1.鬼影出现的原因及解决

    51单片机_数码管动态显示_数码管鬼影_数码管消影



    以郭天祥单片机为例
    wei 指 位&位锁存
    duan 指 段&段锁存
    

    1.鬼影的解决

    1.1先送数,再开锁存

    不好的方式:

    duan = 1;//开锁存
    P0 = 0x45;
    duan = 0;//关锁存
    

    好的方式:

    P0 = 0x45;
    duan = 1;//开锁存
    duan = 0;//关锁存
    

    1.2点亮必熄灭

    如果先送wei,再送duan:送完duan后一定要清除duan。如果不清除,切换下一个wei时会显示上一个duan,出现鬼影。

    P0 = 0x45;
    wei = 1;
    wei = 0;
    
    P0 = 0x45;
    duan = 1;
    duan = 0;
    
    P0 = 0x00;//清除duan
    duan = 1;
    duan = 0;
    

    如果先送duan,再送wei:送完wei后一定要清除wei。如果不清除,此wei会显示下一个duan,出现鬼影。

    P0 = 0x45;
    duan = 1;
    duan = 0;
    
    P0 = 0x45;
    wei = 1;
    wei = 0;
    
    P0 = 0xFF;//清除wei
    wei = 1;
    wei = 0;
    

    1.3初始化

    在单片机上电后,P0口输出值全部为1,此时数码管wei使能全部关闭,duan全部打开,也就是(8.)待亮,一旦wei使能打开就会亮(8.)。
    如果先送wei,再送duan:在送wei的一瞬间,数码管就会亮(8. ),产生鬼影。解决方法:送wei前先初始化,使duan全部关闭,啥也不亮。

    P0 = 0x00;//初始化,关闭断
    duan = 1;
    duan = 0;
    
    wei_latch();
    
    duan_latch();
    

    如果先开duan_latch,再开wei_latch:不会产生鬼影。无需初始化。

    duan_latch();
    
    wei_latch();
    






    2.数值分离的算法

    			digitable[0] = duantable[sec/1%10];
    			digitable[1] = duantable[sec/10%10];
    			digitable[2] = duantable[sec/100%10];
    			digitable[3] = duantable[sec/1000%10];
    			digitable[4] = duantable[sec/10000%10];
    			digitable[5] = duantable[sec/100000%10];
    






    3.将动态扫描放在中断里,1ms扫一次,6ms扫完,1s数值加1,通过标志位,触发数值分离。将数值分离放在while(1)里,查询标志位,每1s触发一次。







    4.代码示例:0-999999计数器

    #include<reg52.h>
    
    #define uchar unsigned char
    #define uint unsigned int
    #define ulong unsigned long
    
    uchar code weitable[6] = 
    {
    	~0x20,~0x10,~0x08,~0x04,~0x02,~0x01
    };
    
    uchar code duantable[16] = 
    {
    	0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
    	0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
    };
    
    uchar digitable[6] = 
    {
    	0x00,0x00,0x00,0x00,0x00,0x00
    };
    
    sbit wei = P2^7;
    sbit duan = P2^6;
    
    ulong sec = 0;
    bit flag = 0;
    uchar i = 0;
    uint cnt = 0;
    
    void main(void)
    {
    	TH0 = 0xFC;
    	TL0 = 0x67;
    	EA = 1;
    	ET0 = 1;
    	TMOD &= ~(0xF<<0);
    	TMOD |= 0x1<<0;
    	TR0 = 1;
    
    	while(1)
    	{
    		if(flag==1)
    		{
    			flag = 0;
    			sec++;
    			if(sec>=1000000)
    			{
    				sec = 0;
    			}
    			digitable[0] = duantable[sec/1%10];
    			digitable[1] = duantable[sec/10%10];
    			digitable[2] = duantable[sec/100%10];
    			digitable[3] = duantable[sec/1000%10];
    			digitable[4] = duantable[sec/10000%10];
    			digitable[5] = duantable[sec/100000%10];
    		}
    	}
    }
    
    void timer0(void) interrupt 1
    {
    	TH0 = 0xFC;
    	TL0 = 0x67;
    	cnt++;
    	if(cnt>=1000)
    	{
    		cnt = 0;
    		flag = 1;
    	}
    
    	P0 = 0x00;
    	duan = 1;
    	duan = 0;
    
    	switch(i)
    	{
    		case 0 : P0=weitable[0];wei=1;wei=0; P0=digitable[0];duan=1;duan=0; i++; break;
    		case 1 : P0=weitable[1];wei=1;wei=0; P0=digitable[1];duan=1;duan=0; i++; break;
    		case 2 : P0=weitable[2];wei=1;wei=0; P0=digitable[2];duan=1;duan=0; i++; break;
    		case 3 : P0=weitable[3];wei=1;wei=0; P0=digitable[3];duan=1;duan=0; i++; break;
    		case 4 : P0=weitable[4];wei=1;wei=0; P0=digitable[4];duan=1;duan=0; i++; break;
    		case 5 : P0=weitable[5];wei=1;wei=0; P0=digitable[5];duan=1;duan=0; i=0; break;
    		default : break;
    	}
    }
    
    展开全文
  • 在本文中,针对数码管的显示,定制了一个七段数码管动态显示接口元件,可以用来驱动1~8个共阴极(或共阳极)数码管的显示,可以根据需要选择小数点显示的位置,每个数码管可以显示0~F之间的十六进制字符,并通过实验...
  • 矩阵键盘+数码管动态显示

    千次阅读 2018-05-16 21:45:42
    我把矩阵键盘和数码管动态显示综合起来写了个程序。这个代码的意思是在一开始8个数码管什么也不显示,因为p0的初始值是0x00,当我们按下矩阵按键里的按键时,8个数码管动态显示该按键的键值,直到按下了下一个按键,8...

    我把矩阵键盘和数码管动态显示综合起来写了个程序。这个代码的意思是在一开始8个数码管什么也不显示,因为p0的初始值是0x00,当我们按下矩阵按键里的按键时,8个数码管动态显示该按键的键值,直到按下了下一个按键,8个数码管显示的内容才可能改变。


    #include<reg52.h>//目的是每按下一个按键,8个数码管就动态显示对应的键值
    sbit lsa=P2^2;
    sbit lsb=P2^3;
    sbit lsc=P2^4;
    #define duanxuan P0
    #define keyboard P1
    int zxm[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    int x,y;
    void delay(int i)
    {
    	while(i--);
    }
    void keyproc()
    {
        int a=0;
    	P1=0x0f;//检测是哪一列有按键按下;
    	if(P1!=0x0f)
    	{
    		delay(1000);
    		if(P1!=0x0f)
    		{
    			P1=0x0f;
    			switch(P1)
    			{
    				case(0x07):y=1;break;
    				case(0x0b):y=2;break;
    				case(0x0d):y=3;break;
    				case(0x0e):y=4;break;
    			}
    		}
    		P1=0xf0;//检测是哪一行有按键按下
    		switch(P1)
    		{
    			case(0x70):x=1;break;
    			case(0xb0):x=2;break;
    			case(0xd0):x=3;break;
    			case(0xe0):x=4;break;
    		}
    		P0=zxm[(x-1)*4+y-1];
    		
    		
    
    	}
    }
    int main()
    {
    	P0=0x00;
    	while(1)
    	{   
    	    lsa=0;lsb=0;lsc=0;//位选选了第1个
    		lsa=1;lsb=0;lsc=0;//位选选了第2个
    		lsa=0;lsb=1;lsc=0;//位选选了第3个
    		lsa=1;lsb=1;lsc=0;//位选选了第4个
    		lsa=0;lsb=0;lsc=1;//位选选了第5个
    		lsa=1;lsb=0;lsc=1;//位选选了第6个
    		lsa=0;lsb=1;lsc=1;//位选选了第7个
    		lsa=1;lsb=1;lsc=1;//位选选了第8个
    		keyproc();
    
    		
    
    		
    		
    		
    	}
    	return 0;
    	
    }

    展开全文
  • 2、了解数码管动态显示方法。 二、实验内容 1、完成读取矩阵键盘并静态显示。 2、完成完成读取矩阵键盘并动态显示。 三、实验原理 四、实验电路与程序 1、软件实验一:完成读取矩阵键盘并静态显示。 1)实验要求:...
  • 实现开发板上8个数码管动态显示0~7.通过实验,掌握采用VerilogHDL语言编程实现7段数码管显示译码器以及数码管动态扫描显示的方法。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,296
精华内容 518
关键字:

数码管动态显示