差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
上一修订版 两侧同时换到之后的修订记录
8._计时控制 [2017/03/23 00:57]
zhijun
8._计时控制 [2018/12/13 14:40]
zhijun [Verilog代码]
行 18: 行 18:
 // >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​ // >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​
 // ******************************************************************** // ********************************************************************
-// File name    : debounce.v +// File name    : counter.v 
-// Module name  : debounce+// Module name  : counter
 // Author ​      : STEP // Author ​      : STEP
 // Description ​ :  // Description ​ : 
行 30: 行 30:
 // V1.0     ​|2017/​03/​02 ​  ​|Initial ver // V1.0     ​|2017/​03/​02 ​  ​|Initial ver
 // -------------------------------------------------------------------- // --------------------------------------------------------------------
-// Module Function:​计时器 +// Module Function:24秒倒计时计数器 
- +  
-module ​segment_counter+module ​counter
 ( (
- clk , + clk , ​   //​时钟 
- rst , + rst , ​   //​复位 
- hold , + hold , ​   //​启动暂停按键 
- seg_led_1 ,​ + seg_led_1 , ​   //​数码管1 
- seg_led_2 ,​+ seg_led_2 , ​   //​数码管2 
 + led                  //led
 ); );
 + 
  input clk,rst;  input clk,rst;
  input hold;​  input hold;​
- +  
- output ​reg [8:​0] seg_led_1,​seg_led_2;​ + output ​ [8:​0] seg_led_1,​seg_led_2;​ 
-  + output reg [7:0] led; 
- reg clk_divided+  
- reg hold_flag;​ + wire clk1h; ​       //​1Hz时钟 
- reg back_to_zero_flag = 0;+ wire hold_pulse; ​  //​按键消抖后信号 
 + reg hold_flag; ​   //​按键标志位 
 + reg back_to_zero_flag ; ​//​计时完成信号
  reg   ​ [6:​0] ​  ​seg [9:​0];  ​  reg   ​ [6:​0] ​  ​seg [9:​0];  ​
- reg [23:​0] cnt;​ + reg [3:​0] cnt_ge; ​     //​个位 
- reg [3:​0] cnt_ge;​ + reg [3:​0] cnt_shi; ​    ​//十位 
- reg [3:​0] cnt_shi;​ + 
-  +
- parameter PERIOD=12000000;​ //1秒 +
- +
  initial ​  initial ​
  begin  begin
行 77: 行 77:
  end  end
   
- always @ (posedge ​clk) begin // 用于分出一个1Hz的频率 + 
- if (!rst == 1begin +  
- cnt <= 0; + // 启动/​暂停按键进行消抖 
- clk_divided <= 0end + debounce ​ U2 ( 
- else begin + .clk(clk)
- if (cnt < PERIOD-1) + .rst(rst),​ 
- cnt ​<= cnt + 1+ .key(hold),​ 
- else begin + .key_pulse(hold_pulse) 
- cnt <= 0; + ); 
- clk_divided ​<= ~clk_dividedend + // 用于分出一个1Hz的频率  
- end + divide #​(.WIDTH(32),​.N(12000000)) U1 (  
- end + .clk(clk),​ 
-  + .rst_n(rst),      ​ 
- always @ (*) begin + .clkout(clk1h) 
- if (!rst == 1) + )
- back_to_zero_flag <= 1+    //​按键动作标志信号产生 
- else if (((cnt_shi*10) + cnt_ge)==24)+ always @ (posedge hold_pulse) 
 + if(!rst==1) 
 + hold_flag ​<= 0
 + else 
 + hold_flag ​<= ~hold_flag
 + //​计时完成标志信号产生 
 + always @ (*) 
 + if(!rst == 1) 
 + back_to_zero_flag <= 0
 + else if(cnt_shi==0 && ​cnt_ge==0)
  back_to_zero_flag <= 1;  back_to_zero_flag <= 1;
  else  else
  back_to_zero_flag <= 0;  back_to_zero_flag <= 0;
- end +    //​24秒倒计时控制 
-  + always @ (posedge ​clk1h or negedge rst) begin 
- always @ (posedge hold) + if (!rst == 1) begin 
- hold_flag <= ~hold_flag;​ + cnt_ge <= 4'd4
-  + cnt_shi <= 4'd2;  
- always @ (posedge ​clk_divided ​or posedge back_to_zero_flag) begin + end 
- if (back_to_zero_flag ​== 1) begin + else if(hold_flag == 1)begin
- cnt_ge <= 0+
- cnt_shi <= 0end +
- else if (cnt_ge == 9) begin +
- cnt_ge <= 0; +
- cnt_shi <= cnt_shi + 1; end +
- else if (hold_flag == 1)+
  cnt_ge <= cnt_ge;  cnt_ge <= cnt_ge;
 + cnt_shi <= cnt_shi;
 + end
 + else if(cnt_shi==0 && cnt_ge==0) begin
 + cnt_shi <= cnt_shi;
 + cnt_ge <= cnt_ge;
 + end
 + else if(cnt_ge==0)begin
 + cnt_ge <= 4'd9;
 + cnt_shi <= cnt_shi-1;​end
  else  else
- cnt_ge <= cnt_ge ​1;+ cnt_ge <= cnt_ge ​-1;
  end  end
-  + //​计时完成点亮led 
- always @ (cnt_ge) begin + always @ ( back_to_zero_flag)begin 
- seg_led_1[8:​0] ​<= {2'​b00,​seg[cnt_ge]};​ + if (back_to_zero_flag==1) 
-   end+ led = 8'​b0;​ 
 + else 
 + led = 8'​b11111111;​ 
 + end 
 + 
 + assign ​seg_led_1[8:​0] = {2'​b00,​seg[cnt_ge]};​ 
 +  
 + assign seg_led_2[8:​0] = {2'​b00,​seg[cnt_shi]};​
  
- always @ (cnt_shi) begin + 
- seg_led_2[8:​0] <= {2'​b00,​seg[cnt_shi]};​ +
- end +
- +
 endmodule endmodule
  
行 129: 行 145:
 \\ \\
  
-以上就是一个N位按键的消抖程序,如果有按键按下会输出一个时钟周期的高脉冲。下面我们可以试试用这个按键消抖的输出来触发LED的显示,既按键一次LED翻转。你也可以不加按键消抖试试用按键来控制LED(按一次变亮,再按一次灭掉)。 
- 
-\\ 
-下面的程序是例化调用debounce模块来控制LED 
-\\ 
-<code verilog> 
-// ******************************************************************** 
-// >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​ 
-// ******************************************************************** 
-// File name    : top.v 
-// Module name  : top 
-// Author ​      : STEP 
-// Description ​ :  
-// Web          : www.stepfpga.com 
-//  
-// -------------------------------------------------------------------- 
-// Code Revision History :  
-// -------------------------------------------------------------------- 
-// Version: |Mod. Date:   ​|Changes Made: 
-// V1.0     ​|2017/​03/​02 ​  ​|Initial ver 
-// -------------------------------------------------------------------- 
-// Module Function:​进过按键消抖后控制led显示翻转 
- 
-module top (clk,​rst,​key,​led);​ 
- 
-        input             clk; 
-        input             rst; 
-        input           key;                       
- output ​  ​reg ​     led;        ​ 
- 
-        wire              key_pulse; 
-        ​ 
-        //​当按键按下时产生一个高脉冲,翻转一次led 
-        always @(posedge clk  or  negedge rst) 
-           begin 
-             if (!rst) ​ 
- led <= 1'b1; 
-      else if (key_pulse) 
- led <= ~led; 
-      else 
-                led <= led; 
-    ​end ​   ​ 
-         //​例化消抖module,这里没有传递参数N,采用了默认的N=1 ​     
-         ​debounce ​ u1 (                                
-                       .clk (clk), 
-                       .rst (rst), 
-                       .key (key), 
-                       ​.key_pulse (key_pulse) 
-                       ); 
- ​endmodule 
-</​code>​ 
- 
-\\ 
 ====引脚分配==== ====引脚分配====
 ------- -------
行 189: 行 152:
 |clk             ​|C1 ​              ^ |clk             ​|C1 ​              ^
 |rst             ​|L14 ​             ^ |rst             ​|L14 ​             ^
-|key             |N14             +|hold            ​|M13              ​
-|led             |N13              ^ +|seg_led_1[0] ​   ​|C12              ^ 
 +|seg_led_1[1] ​   |B14              ^ 
 +|seg_led_1[2] ​   |J1              ^ 
 +|seg_led_1[3] ​   |H1              ^ 
 +|seg_led_1[4] ​   |H2              ^ 
 +|seg_led_1[5] ​   |B12              ^ 
 +|seg_led_1[6] ​   |A11              ^ 
 +|seg_led_1[7] ​   |K1              ^ 
 +|seg_led_1[8] ​   |A12              ^ 
 +|seg_led_2[0] ​   |A10              ^ 
 +|seg_led_2[1] ​   |C11              ^ 
 +|seg_led_2[2] ​   |F2               ^ 
 +|seg_led_2[3] ​   |E1               ^ 
 +|seg_led_2[4] ​   |E2               ^ 
 +|seg_led_2[5] ​   |A9               ^ 
 +|seg_led_2[6] ​   |B9               ^ 
 +|seg_led_2[7] ​   |F1               ^ 
 +|seg_led_2[8] ​   |C9               ^
 ====小结==== ====小结====
 ------ ------
-本实验学习如何进按键消抖在很多应用情况下我们必须采取消抖才能更好地控制逻辑。在下一个实验[[8计时控制|计时控制]]中我们将学习计时的显示和控制,在这里我们要用到按键的消抖以及数码管,我们甚至可以用小脚丫做一个计时器甚至电子表+本实验主要介绍计时器的实现方式,并且包含了复位与暂停功能,读者可自修改程序内部时钟参数来调节计时时间下一节将介绍PWM调制技术的应用[[9呼吸灯|呼吸灯]]。