FPGA多功能数字钟的设计实现

题目:

        在FPGA中设计实现一个多功能数字钟,具备以下功能:

     1.准确计时。能显示时分秒,小时的计时为24进制,分和秒的计时为 60 进制。

  2.准点报时。当“时-分-秒” 为“ XX-59-55、 XX-59-56、 XX-59-57、 XX-59-58、XX-59-59” 时, 蜂鸣器发“ 嘀” ; 当“时-分-秒” 为“ XX-00-00” 时,扬声器发“ 嗒” 。

     3.校时功能。能够对数字钟的时分秒进行精确的调节。

(本实验基于Altera EP4CE10 征途Pro开发板设计实现)

一.设计思路

  该工程主要包括顶层模块Digitalclock和若干个底层模块。计时模块Timer_gen,数码管显示模块display,595控制模块hc595_ctrl,按键消抖模块key_filter,调时模块Adjust以及蜂鸣器控制模块buzzer。

整体的RTL视图如下:

其中display_595模块中包含了对数码管显示模块display,595控制模块hc595_ctrl的例化。

二.FPGA板硬件部分电路原理图

1. 六位八段数码管

其具体使用方法见文章:Altera EP4CE10 征途Pro开发板数码管显示原理(以实现模60计数器为例)-CSDN博客

2. 无源蜂鸣器buzzer

  相对于有源蜂鸣器,无源蜂鸣器的成本更低,声音频率可控。而有源蜂鸣器因其内部自带振荡源,只要加上适当的直流电源即可发声,程序控制较为方便。无源蜂鸣器与有源蜂鸣器不同,因其内部不带震荡源,所以其无法向有缘蜂鸣器那样直接用直流信号驱动,这里需要使用PWM方波才能驱动其发声。

  其具体使用方法见文章:无源蜂鸣器的驱动实验-CSDN博客

3.    按键key

        开发板上使用的机械按键也是按键的一种,特点是:接触电阻小 ,手感好,按键按下或弹起时有“滴答”清脆声;但由于其构造和原理,在按键闭合及断开的瞬间均伴随有一连串的抖动。

       具体按键消抖方法的设计请参阅文章:按键消抖模块设计实现-CSDN博客

三.Verilog代码实现各个模块

1. 计时模块Timer_gen

  计时模块主要包含对时间数据的生成及其如何计数的设计。本模块内包含一个分频器产生标准秒脉冲。模块中同样包含调时信号输入时数字时间的变化。

       调时信号输入时,时间保持不变,由按键进行调时。

  核心部分代码如下:

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		cnt_1s <= 1'b0 ;
	else if( cnt_1s == CNT_MAX )
		cnt_1s <= 1'b0 ;
	else 
		cnt_1s <= cnt_1s + 1'b1 ;

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		clk1 <= 1'b0;
	else if( cnt_1s == CNT_MAX )
		clk1 <= ~clk1 ;
	else
		clk1 <= clk1 ;
		
always@( posedge clk1 or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		begin	
			timer[23:20] <= 4'd0;
			timer[19:16] <= 4'd0;
			timer[15:12] <= 4'd0;
			timer[11:8]  <= 4'd0;
			timer[7:4]	 <= 4'd0;
			timer[3:0] 	 <= 4'd0;
		end
	else if( adjust_h == 1'b0 && adjust_m == 1'b0 && adjust_s == 1'b0)
		begin
			if( (timer[23:20] == 4'd2) && (timer[19:16] == 4'd3) && (timer[15:12] == 4'd5) && (timer[11:8] == 4'd9) && (timer[7:4] == 4'd5) && (timer[3:0] == 4'd9 ) )
				begin
					timer[23:20] <= 4'd0;
					timer[19:16] <= 4'd0;
					timer[15:12] <= 4'd0;
					timer[11:8]  <= 4'd0;
					timer[7:4]	 <= 4'd0;
					timer[3:0] 	 <= 4'd0;
				end
			else if( (timer[19:16] == 4'd3) && (timer[15:12] == 4'd5) && (timer[11:8] == 4'd9) && (timer[7:4] == 4'd5) && (timer[3:0] == 4'd9 ) )
				begin
					timer[23:20] <= timer[23:20] + 1'b1 ;
					timer[19:16] <= 4'd0;
					timer[15:12] <= 4'd0;
					timer[11:8]  <= 4'd0;
					timer[7:4]	 <= 4'd0;
					timer[3:0] 	 <= 4'd0;
				end
			else if( (timer[15:12] == 4'd5) && (timer[11:8] == 4'd9) && (timer[7:4] == 4'd5) && (timer[3:0] == 4'd9 ) )
				begin
					timer[19:16] <= timer[19:16] + 1'b1 ;
					timer[15:12] <= 4'd0;
					timer[11:8]  <= 4'd0;
					timer[7:4]	 <= 4'd0;
					timer[3:0] 	 <= 4'd0;
				end
			else if( (timer[11:8] == 4'd9) && (timer[7:4] == 4'd5) && (timer[3:0] == 4'd9 ) )
				begin
					timer[15:12] <= timer[15:12] + 1'b1 ;
					timer[11:8]  <= 4'd0;
					timer[7:4]	 <= 4'd0;
					timer[3:0] 	 <= 4'd0;                         
				end
			else if( (timer[7:4] == 4'd5) && (timer[3:0] == 4'd9 ) )
				begin
					timer[11:8]  <= timer[11:8] + 1'b1 ;
					timer[7:4]	 <= 4'd0;
					timer[3:0] 	 <= 4'd0;
				end
			else if( (timer[3:0] == 4'd9 ) ) 
				begin
					timer[7:4]	 <= timer[7:4] + 1'b1 ;
					timer[3:0] 	 <= 4'd0;
				end
			else
				begin	
					timer[3:0] <= timer[3:0] + 1'b1 ;
				end
		end
	else if( adjust_h == 1'b1 || adjust_m == 1'b1 || adjust_s == 1'b1 )
		if( adjust_en == 1'b0 )
			begin
				timer[23:20] <= timer[23:20] ;
				timer[19:16] <= timer[19:16] ;
				timer[15:12] <= timer[15:12] ;
				timer[11:8]  <= timer[11:8]  ;
				timer[7:4]	 <= timer[7:4]	 ;
				timer[3:0] 	 <= timer[3:0] 	 ;
			end 
		else if( adjust_en == 1'b1 && adjust_h == 1'b1 )
			begin 
				timer[15:12] <= timer[15:12] ;
				timer[11:8]  <= timer[11:8]  ;
				timer[7:4]	 <= timer[7:4]	 ;
				timer[3:0] 	 <= timer[3:0] 	 ;
				if( timer[23:20] == 4'd2 && timer[19:16] == 4'd3 )
					timer[23:16] <= 8'b0000_0000;
				else if( timer[19:16] == 4'd9 )
					begin 
						timer[23:20] <= timer[23:20] + 1'b1 ;
						timer[19:16] <= 4'd0 ;
					end
				else
					timer[19:16] <= timer[19:16] + 1'b1 ;
				
			end
		else if( adjust_en == 1'b1 && adjust_m == 1'b1 ) 
			begin
				timer[23:20] <= timer[23:20] ;
				timer[19:16] <= timer[19:16] ;
				timer[7:4]	 <= timer[7:4]	 ;
				timer[3:0] 	 <= timer[3:0] 	 ;
				if( timer[15:12] == 4'd5 && timer[11:8] == 4'd9 )
					timer[7:0] <= 8'b0000_0000;
				else if( timer[11:8] == 4'd9 )
					begin 
						timer[15:12] <= timer[15:12] + 1'b1 ;
						timer[11:8] <= 4'd0 ;
					end
				else
					timer[11:8] <= timer[11:8] + 1'b1 ;
			end
		else if( adjust_en == 1'b1 && adjust_s == 1'b1 )
			begin
				timer[23:20] <= timer[23:20] ;
				timer[19:16] <= timer[19:16] ;
				timer[15:12] <= timer[15:12] ;
				timer[11:8]  <= timer[11:8]  ;
				if( timer[7:4] == 4'd5 && timer[3:0] == 4'd9 )
					timer[7:0] <= 8'b0000_0000;
				else if( timer[3:0] == 4'd9 )
					begin 
						timer[7:4] <= timer[7:4] + 1'b1 ;
						timer[3:0] <= 4'd0 ;
					end
				else
					timer[3:0] <= timer[3:0] + 1'b1 ;
			end
	else
		begin
			timer[23:20] <= timer[23:20] ;
			timer[19:16] <= timer[19:16] ;
			timer[15:12] <= timer[15:12] ;
			timer[11:8]  <= timer[11:8]  ;
			timer[7:4]	 <= timer[7:4]	 ;
            timer[3:0] 	 <= timer[3:0] 	 ;
	    end 


2. 数码管显示模块display

  通过动态扫描的方式实现数码管的动态显示。详见:Altera EP4CE10 征途Pro开发板数码管显示原理(以实现模60计数器为例)-CSDN博客

  本实验中主要依靠其进行时分秒的显示。

       当调时信号输入时,调整小时,数码管只显示小时;调整分钟,数码管只显示分钟;调整秒,数码管只显示秒。

  核心代码如下:

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_1ms <=  16'd0;
    else    if(cnt_1ms == CNT_MAX)
        cnt_1ms <=  16'd0;
    else
        cnt_1ms <=  cnt_1ms + 1'b1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        flag_1ms    <=  1'b0;
    else    if(cnt_1ms == CNT_MAX - 1'b1)
        flag_1ms    <=  1'b1;
    else
        flag_1ms    <=  1'b0;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_sel <=  3'd0;
    else    if((cnt_sel == 3'd5) && (flag_1ms == 1'b1))
        cnt_sel <=  3'd0;
    else    if(flag_1ms == 1'b1)
        cnt_sel <=  cnt_sel + 1'b1;
    else
        cnt_sel <=  cnt_sel;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        sel_reg <=  6'b000_000;
    else    if((cnt_sel == 3'd0) && (flag_1ms == 1'b1))
        sel_reg <=  6'b000_001;
    else    if(flag_1ms == 1'b1)
        sel_reg <=  sel_reg << 1;
    else
        sel_reg <=  sel_reg;

always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_disp    <=  4'b0;
    else    if((seg_en == 1'b1) && (flag_1ms == 1'b1))
		begin
			if( adjust_h == 1'b1 )
				case(cnt_sel)
					3'd0:   data_disp    <= 4'd11		;  
					3'd1:   data_disp    <= 4'd11		;  
					3'd2:   data_disp    <= 4'd11		;  
					3'd3:   data_disp    <= 4'd11		;  
					3'd4:   data_disp    <= timer[19:16];  
					3'd5:   data_disp    <= timer[23:20];  
					default:data_disp    <= 4'b0        ;
				endcase
			else if( adjust_m == 1'b1 )
				case(cnt_sel)
					3'd0:   data_disp    <= 4'd11		;  
					3'd1:   data_disp    <= 4'd11		;  
					3'd2:   data_disp    <= timer[11:8] ;  
					3'd3:   data_disp    <= timer[15:12];  
					3'd4:   data_disp    <= 4'd11		;  
					3'd5:   data_disp    <= 4'd11		;  
					default:data_disp    <= 4'b0        ;
				endcase
			else if( adjust_s == 1'b1 )
				case(cnt_sel)
					3'd0:   data_disp    <= timer[3:0]	;  
					3'd1:   data_disp    <= timer[7:4]  ;  
					3'd2:   data_disp    <= 4'd11 		;  
					3'd3:   data_disp    <= 4'd11		;  
					3'd4:   data_disp    <= 4'd11		;  
					3'd5:   data_disp    <= 4'd11		;  
					default:data_disp    <= 4'b0        ;
				endcase
			else 
				case(cnt_sel)
					3'd0:   data_disp    <= timer[3:0]	;  
					3'd1:   data_disp    <= timer[7:4]  ;  
					3'd2:   data_disp    <= timer[11:8] ;  
					3'd3:   data_disp    <= timer[15:12];  
					3'd4:   data_disp    <= timer[19:16];  
					3'd5:   data_disp    <= timer[23:20];  
					default:data_disp    <= 4'b0        ;
				endcase
		end
    else
        data_disp   <=  data_disp;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        dot_disp    <=  1'b1;
    else    if(flag_1ms == 1'b1)
        dot_disp    <=  ~point[cnt_sel];
    else
        dot_disp    <=  dot_disp;

always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        seg <=  8'b1111_1111;
    else    
        case(data_disp)
            4'd0  : seg  <=  {dot_disp,7'b100_0000};    
            4'd1  : seg  <=  {dot_disp,7'b111_1001};    
            4'd2  : seg  <=  {dot_disp,7'b010_0100};    
            4'd3  : seg  <=  {dot_disp,7'b011_0000};    
            4'd4  : seg  <=  {dot_disp,7'b001_1001};    
            4'd5  : seg  <=  {dot_disp,7'b001_0010};    
            4'd6  : seg  <=  {dot_disp,7'b000_0010};    
            4'd7  : seg  <=  {dot_disp,7'b111_1000};    
            4'd8  : seg  <=  {dot_disp,7'b000_0000};    
            4'd9  : seg  <=  {dot_disp,7'b001_0000};    
            4'd10 : seg  <=  8'b1011_1111          ;    
            4'd11 : seg  <=  8'b1111_1111          ;    
            default:seg  <=  8'b1100_0000;
        endcase

3. display_595模块

(对display模块以及hc595_ctr模块l的例化)

module  display_595
(
    input   wire            sys_clk     , 
    input   wire            sys_rst_n   , 
    input   wire    [23:0]  timer       ,
    input   wire    [5:0]   point       , 
    input   wire            seg_en      , 
    input   wire            sign        , 
	input 	wire			adjust_h	,
	input 	wire			adjust_m	,
	input 	wire			adjust_s	,
    input 	wire			adjust_en	,
	
    output  wire            stcp        , 
    output  wire            shcp        , 
    output  wire            ds          , 
    output  wire            oe            

);

wire    [5:0]   sel;    
wire    [7:0]   seg;    


display display_inst
(
    .sys_clk     (sys_clk  ),   
    .sys_rst_n   (sys_rst_n),   
    .timer       (timer    ),   
    .point       (point    ),   
    .seg_en      (seg_en   ),   
    .sign        (sign     ),   
	.adjust_h	 (adjust_h ),
	.adjust_m	 (adjust_m ),
	.adjust_s	 (adjust_s ),
	.adjust_en	 (adjust_en),

    .sel         (sel      ),   
    .seg         (seg      )    

);


hc595_ctrl  hc595_ctrl_inst
(
    .sys_clk     (sys_clk  ),  
    .sys_rst_n   (sys_rst_n),  
    .sel         (sel      ),  
    .seg         (seg      ),  
                               
    .stcp        (stcp     ),  
    .shcp        (shcp     ),  
    .ds          (ds       ),  
    .oe          (oe       )

);

endmodule

4. 蜂鸣器模块buzzer

  准点报时。当“时-分-秒” 为“ XX-59-55、 XX-59-56、 XX-59-57、 XX-59-58、XX-59-59” 时, 蜂鸣器发“ 嘀” ; 当“时-分-秒” 为“ XX-00-00” 时,扬声器发“ 嗒” 。

  其中“ 嘀”用频率为262HZ的DO音,“ 嗒”使用频率为494HZ的SI音。

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		en <= 1'b0 ;
	else if( timer[15:0] == 16'h5955 || timer[15:0] == 16'h5956 || timer[15:0] == 16'h5957 || timer[15:0] == 16'h5958 || timer[15:0] == 16'h5959 || timer[15:0] == 16'h0000 )
		en <= 1'b1 ;
	else
		en <= 1'b0 ;
	
always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		begin	
			freq_data1 <= 18'd0;
			freq_data2 <= 18'd0;
		end
	else if( flag && en )
		begin
			freq_data1 <= DO ;
			freq_data2 <= SI ;
		end
	else
		begin	
			freq_data1 <= 18'd0;
			freq_data2 <= 18'd0;
		end	
	
assign duty_data = ( timer[15:0] == 16'h0000 ) ? 18'd50607 : 18'd95420 ;

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		freq_cnt <= 18'd0 ;
	else
		begin	
			if( timer[15:0] == 16'h0000 )
				begin
					if( freq_cnt == freq_data2 )
						freq_cnt <= 18'd0 ;
					else
						freq_cnt <= freq_cnt + 1'b1 ;
				end
			else if( timer[15:0] == 16'h5959 || timer[15:0] == 16'h5958 || timer[15:0] == 16'h5957 || timer[15:0] == 16'h5956 || timer[15:0] == 16'h5955 )
				begin	
					if( freq_cnt == freq_data1 )
						freq_cnt <= 18'd0 ;
					else
						freq_cnt <= freq_cnt + 1'b1 ;
				end
			else 
				freq_cnt <= 18'd0 ;
		end

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		beepout <= 1'b0 ;
	else if( timer[15:0] == 16'h0000 || timer[15:0] == 16'h5959 || timer[15:0] == 16'h5958 || timer[15:0] == 16'h5957 || timer[15:0] == 16'h5956 || timer[15:0] == 16'h5955 )
		begin
			if ( freq_cnt >= duty_data )
				beepout <= 1'b1 ;
			else
				beepout <= 1'b0 ;
		end	
	else
		beepout <= 1'b0 ;
		

 6.    调时模块Adjust

  按键key1调时按键,其按下时,LED0亮起,表示调时状态;再次按下退出调时,LED熄灭;

  按键key2调分按键,其按下时,LED1亮起,表示调分状态;再次按下退出调分,LED熄灭;

  按键key3调秒按键,其按下时,LED2亮起,表示调秒状态;再次按下退出调秒,LED熄灭;

  按键key4调节按键,其按下时,LED3亮起,表示调节状态,所选中的时或分或秒进行自增调节,再次按下即确定所调时间。

核心代码如下:

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		begin
			adjust_h	<= 1'b0 ;
			adjust_m	<= 1'b0 ;
			adjust_s	<= 1'b0 ;
		end
	else if( adjust_m == 1'b0 && adjust_s == 1'b0 && flag_h == 1'b0 )
		adjust_h <= ~ adjust_h ;
	else if( adjust_h == 1'b0 && adjust_s == 1'b0 && flag_m == 1'b0 )
		adjust_m <= ~ adjust_m ;
	else if( adjust_h == 1'b0 && adjust_m == 1'b0 && flag_s == 1'b0 )
		adjust_s <= ~ adjust_s ;
	else
		begin
			adjust_h  <= adjust_h	;
			adjust_m  <= adjust_m	;
			adjust_s  <= adjust_s	;
		end
	
always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		adjust_en <= 1'b0 ;
	else if( flag == 1'b0 )
		adjust_en <= ~ adjust_en ;
	else 
		adjust_en <= adjust_en ;
		

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		ledout[3] <= 1'b1 ;
	else if( adjust_en && ( adjust_s || adjust_m || adjust_h ) )
		ledout[3] <= 1'b0 ;
	else 
		ledout[3] <= 1'b1 ;

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		ledout[2] <= 1'b1 ;
	else if( adjust_s == 1'b1 )
		ledout[2] <= 1'b0 ;
	else 
		ledout[2] <= 1'b1 ;

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		ledout[1] <= 1'b1 ;
	else if( adjust_m == 1'b1 )
		ledout[1] <= 1'b0 ;
	else 
		ledout[1] <= 1'b1 ;

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		ledout[0] <= 1'b1 ;
	else if( adjust_h == 1'b1 )
		ledout[0] <= 1'b0 ;
	else 
		ledout[0] <= 1'b1 ;

 7.    按键消抖模块key_filter

代码如下:

module  key_filter
(
    input   wire    sys_clk     ,   
    input   wire    sys_rst_n   ,   
    input   wire    key_in      ,   

    output  reg     key_flag        
                                    
);

parameter CNT_MAX = 20'd999_999 	;

reg     [19:0]  cnt_20ms    		;   

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_20ms <= 20'b0;
    else    if(key_in == 1'b1)
        cnt_20ms <= 20'b0;
    else    if(cnt_20ms == CNT_MAX && key_in == 1'b0)
        cnt_20ms <= cnt_20ms;
    else
        cnt_20ms <= cnt_20ms + 1'b1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        key_flag <= 1'b1;
    else    if(cnt_20ms == CNT_MAX - 1'b1)
        key_flag <= ~key_flag;
    else
        key_flag <= 1'b1 ;

endmodule

 8. 顶层模块Digitalclock

  实现对所有底层模块的例化

module Digitalclock
(
		input   wire            sys_clk     ,
		input   wire            sys_rst_n   ,
		input 	wire [3:0]		key_in		,
		
		output 	wire [3:0]		ledout 		,
		output 	wire			beepout		,
		output  wire            stcp        ,
		output  wire            shcp        ,
		output  wire            ds          ,
		output  wire            oe           	
);

wire    [23:0]  timer    ;  
wire    [5:0]   point    ;   
wire            seg_en   ;   
wire            sign     ;   
wire			adjust_en;
wire			adjust_h ; 
wire			adjust_m ; 
wire			adjust_s ; 
 
Timer_gen    Timer_gen_inst
(
    .sys_clk     (sys_clk  ),   
    .sys_rst_n   (sys_rst_n),  
	.adjust_h	 (adjust_h ),
	.adjust_m	 (adjust_m ),
	.adjust_s	 (adjust_s ),
	.adjust_en   (adjust_en),
    
    .timer       (timer    ),   
    .point       (point    ),   
    .seg_en      (seg_en   ),   
    .sign        (sign     )    
);

display_595    display_595_inst
(
    .sys_clk    (sys_clk   ),  
    .sys_rst_n  (sys_rst_n ),  
    .timer      (timer     ),  
    .point      (point     ),  
    .seg_en     (seg_en    ),  
    .sign       (sign      ),  
	.adjust_h	(adjust_h  ),
	.adjust_m	(adjust_m  ),
	.adjust_s	(adjust_s  ),
	.adjust_en	(adjust_en ),

    .stcp       (stcp      ),  
    .shcp       (shcp      ),  
    .ds         (ds        ),  
    .oe         (oe        )   
);

buzzer buzzer_inst
(

	.sys_clk	(sys_clk	),
	.sys_rst_n 	(sys_rst_n 	),
	.timer		(timer		),
	       
	.beepout 	(beepout 	)

);

Adjust Adjust_inst
(

	.sys_clk	(sys_clk	),
	.sys_rst_n	(sys_rst_n	),
	.key_in		(key_in		),
	            
	.ledout     (ledout		),			
	.adjust_h	(adjust_h	),
	.adjust_m	(adjust_m	),
	.adjust_s	(adjust_s	),
	.adjust_en  (adjust_en  )
	

);

endmodule

四. FPGA管脚配置

  通过查询开发板硬件电路原理图可知:

五.工程运行烧录结果

  实现00-00-00到23-59-59的24小时数字钟显示,并有整点报时以及调时功能。

下图显示时间01-02-39:

下图显示调时状态,数码管只显示小时,LED0亮起;LED3亮起,时自增调节:

  • 30
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是既白呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值