差别

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

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
book_excise_digital_clock [2021/08/19 22:58]
gongyusu [2. 实验原理]
book_excise_digital_clock [2021/08/20 12:20] (当前版本)
zili
行 1: 行 1:
 +## 数字钟实验
  
 +### 1. 实验内容
 +本实验设计一个能够显示时、分、秒钟的数字时钟,时间在7段数码管上显示。通过开发板上的按键调整数字时钟的时间,分别用四个键来控制分、时的增减。各按键及数码管功能要求如表12-1所示。
 +<WRAP centeralign>​
 +**表12-1 按键及数码管功能要求**
 +</​WRAP>​
 +|数码管L13、L14|秒钟显示|reset|时钟复位|
 +|数码管L12,​L11|分钟显示|S3,S7|小时加减|
 +|数码管L10,​L9|小时显示|S6,​S10|分钟加减|
 +按下S1,则时钟复位;L13,L14显示秒;按下键盘区的S3键,L12即分钟数增1,同时数码管L7和L8显示S3所在的行列值。同样,按下S7为分钟数减1,S6为小时数增1,数码管L10上的数字相应增1,S10为小时数减1。
 +
 +\\
 +\\
 ### 2. 实验原理 ### 2. 实验原理
 本实验的原理较为简单(图12 1),设计一个时钟产生模块,产生周期为1s的计时时钟和周期为4ms键盘扫描时钟。周期为1s的时钟触发“秒”计时,计时到59发生分钟的进位,并触发分钟的计时,同样分钟计时到59发生小时的进位,并触发小时的计时。通过键盘上的某些键可以手动设置小时和分钟,时间和键值都会在数码管上显示。键盘键值的识别和数码管的显示参看《键盘扫锚及数码管实验》。 本实验的原理较为简单(图12 1),设计一个时钟产生模块,产生周期为1s的计时时钟和周期为4ms键盘扫描时钟。周期为1s的时钟触发“秒”计时,计时到59发生分钟的进位,并触发分钟的计时,同样分钟计时到59发生小时的进位,并触发小时的计时。通过键盘上的某些键可以手动设置小时和分钟,时间和键值都会在数码管上显示。键盘键值的识别和数码管的显示参看《键盘扫锚及数码管实验》。
-{{ :​图12-1.png |图12-1 数字时钟原理示意图}} 
 {{drawio>​zzcbook_digitalclock.png}} {{drawio>​zzcbook_digitalclock.png}}
 +
 +<WRAP centeralign>​ **图12-1 数字时钟原理示意图** </​WRAP>​
 +
 +### 3. 实验设计
 +#### 3.1 总体架构 ​
 +程序由以下模块组成(图 12 2):\\
 +1. 顶层模块Digital_clk将各子模块实例化并将各模块连接起来。
 +2. clk_gen模块产生扫描键盘所要求的周期为4ms的脉冲信号和计数需要的周期为1秒钟的脉冲信号。\\
 +3. scan和前面的键盘扫描与数码管显示实验的一样,负责键盘的扫描识别。\\
 +4. scan模块扫描到的键盘列值和行值送给Timeset模块。Timeset模块用来识别手动时间设置的模式,如按下键盘S3,则表示小时加1。\\
 +5. Time模块是本程序的核心模块,实现一个支持时分秒的时钟。\\
 +6. data_2_disp模块和disp_scan也与前面的键盘扫描与数码管显示实验的一样。这里用到六个data_2_disp模块,​ disp1,disp0显示秒针;disp3,disp2显示分钟;disp5,disp4显示小时。
 +
 +{{ :​图12-2.png |图12-2 程序总体框图}}
 <WRAP centeralign>​ <WRAP centeralign>​
-**图12-1 数字时钟原理示意图**+**图12-2 程序总体框图**
 </​WRAP>​ </​WRAP>​
 +
 +#### 3.2 Digital_clk模块(digital_clk.v)
 +Digital_clk模块为顶层模块,输入输出接口如下:
 +<code verilog> ​
 +
 +input clk,​reset;​ //​时钟和复位信号。
 +input [3:​0]kr;​ //​扫描键盘行输入。
 +output [3:​0]kc;​ //​扫描键盘列输出。
 +output [7:​0]HEX_sel;​ //​数码管显示选通信号,每一位选通一个数码管。
 +output [7:​0]HEX_seg;​ //​数码管译码显示的内容。
 +
 +</​code>​
 +
 +#### 3.3 one_sec模块(one_sec.v)
 +One_sec产生以1s为周期的时钟和以4ms为周期的键盘扫描时钟,输入输出接口如下:
 +<code verilog> ​
 +
 +input clk, reset;​ //​时钟和复位信号。
 +output one_sec_clk;​ //​周期为1s的时钟输出
 +output scan_clk;​  ​   //​周期为4ms的键盘扫描时钟输出
 +
 +</​code>​
 +
 +#### 3.3 Time_set模块(Time_set.v)
 +Time_set实现对时钟小时和分钟的手动设置,​输入输出接口如下:
 +
 +<code verilog> ​
 +
 + input [3:0] add_r; ​        //​按键行地址
 + input [3:0] add_c; ​        //​按键列地址
 + output [3:0] set;          //​手动手动设置时间信号
 +Time_set是一个组合逻辑模块,通过按键值来决定时间的调整方式。定义set来指示是何种调整方式,set有四种取值,如下列代码所示:
 +always @(r_reg or c_reg)
 + begin
 + if(r_reg == 4'​b0001)
 + begin
 + if(c_reg == 4'​b0100) //​按下S3分钟加1
 + set = 4'​b0010;​
 + else if(c_reg == 4'​b0001) //​按下S6小时加1
 + set = 4'​b0001;​
 + else
 + set = 4'​b0000;​
 + end
 + else if(r_reg == 4'​b0010)
 + begin
 + if(c_reg == 4'​b0100) //​按下S7分钟减1
 + set = 4'​b1000;​
 + else if(c_reg == 4'​b0001) //​按下S10小时减1
 + set = 4'​b0100;​
 + else
 + set = 4'​b0000;​
 + end
 + else
 + set = 4'​b0000;​
 + end
 +endmodule
 +
 +</​code>​
 +
 +
 +#### 3.5 Time模块(Time.v)
 +Time模块控制数字时钟的“时”、“分”及“秒”,模块输入输出接口如下:
 +<code verilog> ​
 +
 +input clk, reset;​ //​时钟和复位信号。
 +input en_sec;​ //​输入周期为1s的时钟 。
 +input [3:​0]set;​ //​手动时间设置控制输入。
 +output [7:​0]sec;​ //​输出秒。
 +output [7:​0]minu;​ //​输出分钟。
 +output [7:​0]hour;​ //​输出小时。
 +
 +</​code>​
 +
 +以下以小时位的增减来说明如何控制“时”“分”“秒”。\\
 +当键盘有控制键按下时表示需要手动调节分钟和小时,如set=0001,说明输入的按键是S6,则en_h_manu赋值为1。
 +
 +<code verilog> ​
 +
 +if(keyout_en) ​  //​键盘输入使能信号为高时,set输入有效
 +    case(set)//​手动控制分钟与小时的增减
 +        4'​b0001:​ begin
 +             ​en_m_manu <= 0;​ en_h_manu <= 1; de_m <= 0; de_h <= 0;
 +        end//​手动小时增1
 +        //​四个信号的含义为:
 +        // en_h_manu为高时表示小时手动调整,de_h为高时表示减1,为低时表示加1。
 +        // en_m_manu为高时表示分钟手动调整,de_m为高时表示减1,为底时表示加1。
 + 4’b0010: begin
 +            en_m_manu <= 1;​ en_h_manu <= 0; de_m <= 0; de_h <= 0;
 +        end//​手动分钟增1。
 +        4'​b0100: ​ begin
 +            en_m_manu <= 0;​ en_h_manu <= 0; de_m <= 0; de_h <= 1;
 +        end//​手动小时减1。
 + 4'​b1000:​ begin
 +            en_m_manu <= 0;​ en_h_manu <= 0; de_m <= 1; de_h <= 0;
 +        end//​手动分钟减1。
 +        default: ​ begin
 +            en_m_manu <= 0;​ en_h_manu <= 0; de_m <= 0; de_h <= 0;
 +        end  ​
 +    endcase
 +
 +</​code>​
 +
 +当分钟位计时到59时,产生一个小时位自动增加变量en_h_auto置为1。\\
 +信号en_m_manu和en_m_auto分别控制手动和自动分钟调整,定义信号en_m表示分钟需要调整:\\
 +assign en_m = en_m_manu | en_m_auto;​\\
 +
 +下列代码判断分钟是否需要向小时进位,如果分钟需要调整且分钟计数值到59,则需要向小时进位:
 +<code verilog> ​
 +
 +always @(en_m or COUNTERm) ​  // COUNTERm表示分钟计数。
 +    begin
 +        en_h_auto <= 0;
 + if(en_m) ​    //​分钟需要调整。
 + begin
 +         if(COUNTERm == 6'​b11_1011)//​计数到59。
 +     en_h_auto <= 1; //​en_h_auto表示小时需要自动调整。
 + else
 +     en_h_auto <= 0;
 + end
 + else
 +      ​en_h_auto <= 0;
 +    end
 +
 +</​code>​
 +
 +信号en_h 表示小时是否需要增加,en_h = en_h_manu | en_h_auto。即无论是用按键手动控制还是分钟自动产生进位信号,小时数都要增加1。小时是以24为循环所以当计数到23时,小时计数COUNTERh置为0。当按键产生小时减少信号de_h时,​小时数COUNTERh减1:
 +
 +<code verilog> ​
 +
 +always@( posedge clk or  negedge reset) begin: calculate_hourur
 +    if (!reset)
 +        COUNTERh <= 5'b0;
 +    else begin 
 +        if(en_h) begin
 +            if(COUNTERh == 5'​b1_0111)//​计数到23
 +                COUNTERh <= 5'b0;
 +     else
 + COUNTERh <= COUNTERh+1'​b1;​小时加1
 +   end
 +        else if(de_h) ​         //​小时位减1信号
 +     begin
 + if(COUNTERh == 5'​b0_0000)//​当小时位为0时,减1
 + COUNTERh <= 5'​b1_0111;//​小时位变为23
 + else 
 + COUNTERh <= COUNTERh-1'​b1;​
 +            end
 + end
 +    end
 +
 +</​code>​
 +
 +因为是用两位十进制来显示小时数,所以需要把二进制数COUNTERh转换成十进制表示。hour[7:​0]的前四位为十位,后四位为个位。
 +<code verilog> ​
 +assign ​  ​hour[7:​4] = COUNTERh/​10;//​小时十位数
 +assign ​  ​hour[3:​0] = COUNTERh%10;​ //​小时个位数
 +
 +</​code>​
 +
 +(5)scan模块,data_2_disp模块和disp_scan与键盘扫描与数码管显示实验中的一样,请参考键盘扫描实验。
  
 \\ \\
-\+\
 +### 4. 仿真结果 
 +{{ :​图12-3.png |图12-3 增大小时值}} 
 +<WRAP centeralign>​ 
 +**图12-3 增大小时值** 
 +</​WRAP>​ 
 + 
 +在图12 3中的黄色线处:set=0001,​此时增加小时,所以置en_h_manu为高,en_h是en_h_manu和en_h_auto逻辑“或”的结果,所以此时en_h也为高电平,使hour的值加1;\\ 
 +红色线处:set=0010,​此时增加分钟,所以置en_m_manu为高,en_m是en_m_manu和en_m_auto或的结果,所以此时en_m也为高电平,使minu的值加1。 
 + 
 +{{ :​图12-4.png |图12-4 减小分钟值}} 
 +<WRAP centeralign>​ 
 +**图12-4 减小分钟值** 
 +</​WRAP>​ 
 + 
 +在图12-4中的紫色线处:set=1000,​此时减小小时的值,所以置de_h为高,使hour的减1,从01变到00;\\ 
 + 
 + 
 +{{ :​图12-5.png |图12-5 减小分钟值}} 
 +<WRAP centeralign>​ 
 +**图12-5 减小分钟值** 
 +</​WRAP>​ 
 + 
 +图 12 5是在没有调整时间情况下,在sec=59且en_sec=1时置en_m_auto为高电平,使分钟加1;在minu=59且en_m=1时置en_h_auto为高电平,使小时加1。\\ 
 +在上面三个图中sec、minu、hour的显示格式都是16进制形式。 
 + 
 +\\ 
 +\\ 
 +### 5. 演示程序文件说明 
 +|文件名|功能| 
 +|Digital_Clk.v|主程序| 
 +|one_sec.v|产生1s周期时钟和键盘扫描时钟| 
 +|clock.v|数字钟| 
 +|scan.v|键盘扫描| 
 +|disp_scan.v|数码管扫描| 
 +|data_2_disp.v|数码管译码| 
 + 
 +\\ 
 +\\ 
 +### 6. 演示程序使用 
 +演示设备要求:核心板,扩展板。 
 + 
 +演示方法:下载后,可以看到数码管L14 由零开始计数,L13,L14为秒数显示,按下键盘区的S3键,可以观察到L12即分钟数增1,同时数码管L7L8显示14,即S3所在的行列值。同样,按下S7键为分钟数减1,S6键为小时数增1,数码管L10上的数字会相应增1,S10键为小时数减1。所按键的行列值都会在L7L8上显示。核心板Reset键为复位键。 
 +