zoukankan      html  css  js  c++  java
  • 可调时钟

      1 /**********************************************
      2 
      3 工程名:可调时钟
      4 模块名: clock
      5 
      6 -----------------------------------------------
      7 IO说明:
      8     clk:            50MHZ时钟
      9     key_in[3:0]:        四位独立按键
     10     seg_out[7:0]:        七段数码管段选
     11     seg_en[7:0]:        八个数码管位选
     12 -----------------------------------------------
     13 操作说明:
     14 key[0] :set键       调时/选位
     15 key[1] :inc键     增加 
     16 key[2] :sub键     减小
     17 key[3] :ok键      确认
     18 
     19 1. 默认为计时状态,此时点下set键,进入调时状态
     20 2. 此时秒位闪烁,此时点下 inc/sub键,即可调时
     21 3:长按inc/sub键,进行快速调时,每秒加减10次
     22 4:再点下set键,即可更换调时位
     23 5:调完后按下ok键,恢复计时
     24 
     25 ------------------------------------------------
     26 
     27 时间:2012年6月24日
     28 作者:刘文武
     29 
     30 ***********************************************/
     31 module clock(
     32     clk,    
     33     key_in,
     34     seg_out,
     35     seg_en
     36 );
     37 
     38 
     39 input clk; 
     40 input [3:0] key_in;    
     41 output [7:0] seg_out; 
     42 output [7:0] seg_en;
     43 
     44 //时间寄存器
     45 reg [5:0] min,sec;    
     46 reg [4:0] hour;
     47 
     48 //a时    b分   c秒
     49 //1十位      2个位
     50 reg [31:0] a1,a2,b1,b2,c1,c2;
     51 
     52 
     53 reg clk_1khz ;          //用于数码管扫描
     54 reg clk_10hz;           //用于更新时间数据
     55 reg clk_1_2hz;          //用于数码管闪烁
     56 
     57 reg [7:0] seg_out ;     //数码管段选
     58 reg [7:0] seg_en;       //数码管位选
     59 
     60 reg state;              //状态位,计时为0,调时为1
     61 reg [7:0]en_buf;        //en缓冲
     62 reg [2:0] set_pos;      //调时位:{时,分,秒}
     63 reg [3:0] key_buf;      //读键缓冲
     64 
     65 
     66 //寄存器初始化
     67 //----------------------------------------
     68 initial
     69  begin
     70       count <= 24'b1 ;
     71       set_pos <=3'b001;
     72       en_buf <= 8'b1111_1110;
     73       seg_out <= 8'b1111_1111 ;
     74  end
     75 
     76 //分频
     77 //------------------------------------------
     78 reg [24:0] count ;
     79 
     80 always @ (posedge clk )
     81 begin
     82 
     83  if( count == 25000000 ) count <= 1 ;    
     84  else count <= count + 1'b1;
     85 
     86 if(count % 12500000 == 0 )   clk_1_2hz <= ~ clk_1_2hz;      //1_2HZ             
     87 if(count % 2500000 == 0 )    clk_10hz <= ~ clk_10hz;        //10HZ
     88 if(count % 25000 == 0 )      clk_1khz <= ~ clk_1khz;        //1kHZ
     89         
     90 end
     91 
     92 
     93 //数码管扫描
     94 //------------------------------------------
     95 always @ (posedge clk_1khz)
     96 begin
     97  
     98 // 计算时间位    
     99     a1<=hour/10;
    100     a2<=hour%10;
    101     b1<=min/10;
    102     b2<=min%10;
    103     c1<=sec/10; 
    104     c2<=sec%10;
    105 //动态扫描
    106     seg_en<=en_buf;
    107     case (en_buf)
    108             //在调时状态下,该调试位为真,且1/2Hz时钟到来时,该数码管灭,实现闪烁效果
    109     8'b1111_1110 :   seg_out <= (state && set_pos[0]&& clk_1_2hz) ? 8'b1111_1111:zimu(a1);        
    110     8'b1111_1101 :   seg_out <= (state && set_pos[0] && clk_1_2hz) ? 8'b1111_1111: zimu(a2);
    111     8'b1111_1011 :   seg_out <= 8'b1011_1111;    //显示"-"
    112     8'b1111_0111 :   seg_out <= (state && set_pos[1] && clk_1_2hz) ? 8'b1111_1111:zimu(b1);
    113     8'b1110_1111 :   seg_out <= (state && set_pos[1] && clk_1_2hz) ? 8'b1111_1111:zimu(b2);
    114     8'b1101_1111 :   seg_out <= 8'b1011_1111;    //显示"-"
    115     8'b1011_1111 :   seg_out <= (state && set_pos[2] && clk_1_2hz) ? 8'b1111_1111:zimu(c1);
    116     8'b0111_1111 :   seg_out <= (state && set_pos[2] && clk_1_2hz) ? 8'b1111_1111:zimu(c2);
    117     default :    en_buf <=  8'b1111_1110;
    118     endcase
    119     //位选寄存器环形移位
    120     if(en_buf == 8'b0111_1111)    en_buf  <=  8'b1111_1110;
    121     else    en_buf  <= ~( ( ~en_buf ) << 1 );
    122             
    123 end 
    124 
    125 
    126 //按键消抖
    127 //-----------------------------------------------
    128 reg [19:0] key_count;
    129 
    130 always @ (posedge clk)
    131 begin
    132  if(key_in != 4'b1111)    //判断是否有键按下
    133  begin
    134     key_count <= key_count+1'b1;//当检测到有键按下,计数器加1
    135     key_buf <= 4'b1111;//此时延时尚未达到,所以输出为高
    136 
    137     if(key_count>=20'd1000000)
    138     begin
    139     key_count<=20'd1000001;//当达到延时200us(50MHZ)时,锁存key-count值
    140     key_buf <= key_in; //此时延时达到200us,输出为低
    141     end
    142  end
    143  else 
    144  begin
    145      key_buf <= 4'b1111; //当没有键按下时, 输出为高
    146      key_count <= 1'b0; //计数器清0
    147  end
    148 
    149 end
    150 
    151 //模式选择
    152 //---------------------------------------------------
    153 reg [3:0] count2;
    154 
    155 always @ (posedge clk_10hz)
    156 begin
    157 
    158         if(state == 0)
    159             begin
    160                 //计时状态下,检测到set键按下,转为调时模式
    161                 if(key_buf[0]==0) state <= 1'b1;
    162              
    163              
    164                 if(count2==4'd9) 
    165                 begin
    166                     count2<=4'b0;
    167                     //0.1s * 10 = 1s
    168                     timerun(sec,min,hour);
    169                 end            
    170                 else count2<=count2+1'b1;
    171             end
    172         else timeset(sec,min,hour,set_pos,key_buf);
    173     end
    174 
    175 
    176  //取字模函数
    177  //---------------------------------------------------
    178 
    179 function [7:0] zimu;
    180     input [3:0]num;
    181     begin
    182     case(num)
    183         4'b0000:         zimu = 8'b1100_0000;    // "0"        
    184         4'b0001:         zimu = 8'b1111_1001;    // "1"
    185         4'b0010:         zimu = 8'b1010_0100;    // "2"
    186         4'b0011:         zimu = 8'b1011_0000;    // "3"
    187         4'b0100:         zimu = 8'b1001_1001;    // "4"
    188         4'b0101:         zimu = 8'b1001_0010;    // "5"
    189         4'b0110:         zimu = 8'b1000_0010;    // "6"
    190         4'b0111:         zimu = 8'b1111_1000;    // "7"
    191         4'b1000:         zimu = 8'b1000_0000;    // "8"
    192         4'b1001:         zimu = 8'b1001_0000;    // "9"
    193         default :        zimu = 8'bx;           //不确定
    194     endcase    
    195     end
    196 
    197 endfunction
    198 
    199 //计时任务
    200 //------------------------------------------------
    201 task timerun;
    202 inout [5:0] sec,min;
    203 inout [4:0] hour;
    204 begin
    205 if(sec==6'd59)
    206 begin
    207     sec<=6'b0;
    208     if(min==6'd59)
    209     begin
    210         min<=6'b0;
    211         if(hour == 5'd23)
    212             hour<=5'b0;
    213         else
    214             hour<=hour+1'b1;
    215     end
    216     else
    217     min<=min+1'b1;
    218 end
    219 else
    220 sec<=sec+1'b1;
    221 end
    222 endtask    
    223 
    224 
    225 //调时任务
    226 //------------------------------------------------
    227 task timeset;
    228 
    229 inout [5:0] sec,min;
    230 inout [4:0] hour;
    231 inout [2:0] set_pos;
    232 input [3:0] key_buf;
    233 
    234 begin
    235 
    236 if(key_buf[0]==0)//按下set键,调试位左移,时<-分<-秒
    237     begin
    238         if(set_pos==3'b100) set_pos<=3'b001;
    239         else set_pos<=set_pos<<1;
    240     end
    241     else if (key_buf[1]==0)//按下inc键,调试位+
    242     begin
    243     
    244         case(set_pos)
    245         3'b100: begin if(sec==6'd59) sec<=6'd0; else sec<= sec+1'b1;        end    //秒+
    246         3'b010: begin if(min==6'd59) min<=6'd0; else min<= min+1'b1;        end    //分+
    247         3'b001: begin if(hour==5'd23) hour<=5'd0; else hour<= hour+1'b1;    end    //时+
    248         default:;
    249         endcase
    250     end
    251     else if (key_buf[2]==0)//按下sub键,调试位-
    252     begin
    253         case(set_pos)
    254         3'b100: begin if(sec==6'd00) sec<=6'd59; else sec<= sec-1'b1;        end    //秒-
    255         3'b010: begin if(min==6'd00) min<=6'd59; else min<= min-1'b1;        end    //分-
    256         3'b001: begin if(hour==5'd00) hour<=5'd23; else hour<= hour-1'b1;    end    //时-
    257         default:;
    258         endcase
    259     end
    260     else if (key_buf[3]==0)//按下ok键,退出调时模式
    261         state<= 1'b0;
    262 
    263 end
    264 endtask
    265 
    266 
    267 //-----------------------------------------------
    268 
    269 endmodule
  • 相关阅读:
    Linux内核的总结认识
    服务器的基本问题避免
    Linux中多线程信号的处理
    gdb调试
    TCP数据包的封包和拆包
    网络TCp数据的传输设计(黏包处理)
    InputArray和OutputArray
    UTF8转unicode说明
    C++使用标准库的栈和队列
    resize函数有五种插值算法
  • 原文地址:https://www.cnblogs.com/sky1991/p/2560442.html
Copyright © 2011-2022 走看看