新闻  |   论坛  |   博客  |   在线研讨会
基于FPGA的数字时钟数码管显示
啸风 | 2012-10-20 16:03:44    阅读:9437   发布文章

看来自己的真的是一名博客菜鸟啊,刚写了那么多,就下面的引用地址没写,提交后就拜拜了,又的重新再来了。

今天开始我就开始了FPGA开发不能DIY的博客之旅

        本实验是数码管、按键、分频的综合实验,要求:用硬件描述语言verilog设计一个具有时、分、秒计数显示功能,以24小时循环计时的时钟电路,带有一键清零、以及秒、分、时校准的功能。下图是本设计的系统框图:





24小时计时时钟电路是对系统时钟进行分频到1Hz,下面是流程图:



       按键控制模块中包括:清零键(clr)、设置键(set)、模式选择键(mode)。当清零键按下,时钟电路清零,数码显示零。设置键跟模式选择一起使用,对电路进行校准。各种模式的状态图如下:




当这些都准备好了,你就开始你的工程吧,下面是整个工程的RTL视图:



以下是核心源码:


module clock(
             clk,
             mode,set,clr,
             segdat,sl
             );

 

  input clk;
  input mode,set,clr;
  output segdat,sl;
  wire[7: 0] segdat,sl;
  wire[7: 0]sec,min,hour;
  wire[7: 0]BCD_sec,BCD_min,BCD_hour;
 
  //时钟控制模块例化
  time_control u_time_control(
                              .mode(mode),
                              .clr(clr),
                              .clk(clk),
                              .set(set),                             
                              .sec(sec),
                              .min(min),
                              .hour(hour)
                              );
                             
   //秒BCD码例化
  bcd u_sec(
           .datain(sec),
           .BCD_Out(BCD_sec)
           );
 
  //分钟BCD码例化
  bcd u_min(
           .datain(min),
           .BCD_Out(BCD_min)
           );
 
  //小时BCD码例化
  bcd u_hour(
           .datain(hour),
           .BCD_Out(BCD_hour)
           );
 //数码管显示例化         
  display u_display(
                    .clk(clk),
                    //.rst_n(rst_n),
                    .sec(BCD_sec),
                    .min(BCD_min),
                    .hour(BCD_hour),
                    .segdat(segdat),
                    .sl(sl)
                    );
endmodule 

module time_control(
            mode,clr,clk,set,
            sec,min,hour
           );
  input mode,clr,clk,set;
  output sec,min,hour;           
  reg[1:0] state;
  reg [7:0] sec,min,hour;       //秒和分处理寄存器
 
//模式选择
//state = 2'b00 时钟计时
//state = 2'b01 小时校准
//state = 2'b10 分钟校准
//state = 2'b11 秒校准
 
  always @(negedge mode or negedge clr)
     if(!clr)
       state = 2'b00;
     else if(!mode)
       begin
         case(state)
           2'b00: state = 2'b01;
           2'b01: state = 2'b10;
           2'b10: state = 2'b11;
           2'b11: state = 2'b00;
         endcase
       end
   
    reg[25: 0] clk_cnt;  
    reg set_r;
   
  always @(posedge clk or negedge clr)
    if(!clr)
      begin
         sec = 8'd0;
         min = 8'd0;
         hour = 8'd0;
         clk_cnt = 0;
         set_r = 1'b0;
      end 
    else
      begin
        case(state)
          2'b00:                                      //24小时计数
                if(clk_cnt == 26'd50000000)           //对50M时钟进行分频得1Hz的时钟
                   begin
                     clk_cnt = 25'd0;
                     if(sec == 8'd59)
                       begin
                         sec = 8'd0;
                         if(min == 8'd59)             //时钟计数
                           begin
                             min = 8'd0;
                             if(hour == 8'd23)
                               hour = 8'd0;
                             else
                               hour = hour + 1'b1;
                           end
                         else
                           min = min + 1'b1;
                       end
                     else
                       sec = sec + 1'b1;
                   end
                else
                  clk_cnt = clk_cnt + 1'b1;
       
          2'b01:                                        //小时校准
                if(!set)
                  begin
                    if(set_r == 1'b0)
                      begin
                        set_r =1'b1;
                        if(hour == 8'd23)
                          hour = 8'd0;
                        else
                          hour = hour + 1'b1;
                      end
                  end
                else
                  set_r = 1'b0;
                 
          2'b10:                                        //分钟校准
                if(!set)
                  begin
                    if(set_r == 1'b0)
                      begin
                        set_r = 1'b1;
                        if(min == 8'd59)
                          min = 8'd0;
                        else
                          min = min + 1'b1;
                      end
                  end
                else
                  set_r = 1'b0;        
        

          2'b11:                                       //秒校准
                if(!set)
                  begin
                    if(set_r == 1'b0)
                      begin
                        set_r =1'b1;
                        if(sec == 8'd59)
                          sec = 8'd0;
                        else
                          sec = sec + 1'b1;
                      end
                  end
                else
                  set_r = 1'b0;          
                              
      
        endcase
      end 
endmodule
       

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
堂主家的芯食堂开张了,欢迎各位客官进来品尝~
推荐文章
最近访客