基于FPGA的数字钟设计---第三版

fpga · 浏览次数 : 0

小编点评

**数字钟设计思想** 1. **外部调整脉冲控制工作状态**:根据外部的调整脉冲,确定工作状态。 2. **24小时进制计时**:如果当前时间是正常模式,只显示时和分。 3. **12小时进制计时**:如果当前时间是12时或以上,需要减去12小时。 4. **调整模式计时**:在调整模式中,启动一秒钟的计时器。 5. **正常模式计时**:在正常模式下,需要显示的时、分、秒的十位和个位计算出来。 6. **调整模式计时**:在调整模式下,需要前半秒输出对应的数字,后半秒输出全F。 7. **数字管驱动**:当输入正常数字0~9显示数字时,数码管熄灭,此时数码管就闪烁起来了。

正文

欢迎各位朋友关注“郝旭帅电子设计团队”,本篇为各位朋友介绍基于FPGA的数字钟设计---第三版。

功能说明:

 1. 在数码管上面显示时分秒(共计六个数码管,前两个显示小时;中间两个显示分钟;最后两个显示秒)。

   2. 利用按键可以切换24/12小时制(默认24小时制)。

   3. led1的亮灭表示24小时制(亮)还是12小时制(灭)。

   4. led2的亮灭表示上午(亮)还是下午(灭),24小时制时,一直灭。

   5. 增加调整按键和加减按键。

   6. 调整按键不按下时,正常显示时分秒。       

    按下第一次,进入调整状态,时间停止,并且小时开始闪烁,通过加减按键可以进行调整。       

    按下第二次,分钟开始闪烁,通过加减按键可以进行调整。       

    按下第三次,秒开始闪烁,通过加减按键可以进行调整。       

    按下第四次,进入正常运行状态。       

   后续再按下时,重复以上的过程

  

使用平台:本次设计应用Altera的平台设计(芯片:EP4CE10F17C8N)。

仿真平台:Modelsim。

作者QQ:746833924

说明:本篇设计中不涉及到IP和原语,代码在其他平台依然可以适用;当其他板卡电路不同时,会导致不同的现象出现,如有需要修改代码请联系作者;如需作者使用的板卡,请联系作者;

 

设计思想如下:

 

    

        key_ctrl模块负责将外部的按键信号进行消抖,并且产生对应边沿变化时的脉冲;digital_clock_ctrl模块负责根据脉冲信号和设计逻辑产生对应数字逻辑和led的状态;seven_tube_drive(七段数码管驱动)模块负责将digital_clock_ctrl模块产生的数字逻辑显示到数码管上。

 

key_ctrl模块设计思想为:按键信号是由外部机械式按键产生,每次按下或者抬起时,会产生一定的抖动。如果直接对其进行边沿检测就会导致多次触发。故而需要设计按键消抖,进而对消抖之后的波形进行边沿检测。消抖原理为:外部按键信号发生改变后,如果能够持续20ms,没有新的改变,就认为此次改变不是抖动,而是真正的按下,然后进行采样即可。

 

// 记录任意边沿之后没有遇到新的边沿的时间长度是否达到20Ms 

//---------------------------------------------------------------------------------------  

always@(posedgeclk)begin

   if(rst_n ==1'b0)

     cnt_20ms <=20'd0;

   else

     if(pulse_key_negedge ==1'b1||pulse_key_posedge ==1'b1)

       cnt_20ms <=20'd1;

     else

       if(cnt_20ms >20'd0&&cnt_20ms <T_20ms)

         cnt_20ms <=cnt_20ms +1'b1;

       else

           cnt_20ms <=20'd0;

 end

// --------------------------------------------------------------------------------------- 

// 任意边沿之后没有遇到新的边沿的时间长度达到20Ms,认为按键稳定,此时采样 

//--------------------------------------------------------------------------------------    

always@(posedgeclk)begin

   if(rst_n ==1'b0)

     key_wave <=1'b1;

   else

     if(cnt_20ms ==T_20ms)

       key_wave <=key_rr;

     else

       key_wave <=key_wave;

 end

//--------------------------------------------------------------------------------------

// 对消抖之后的按键信号进行边沿检测 

//---------------------------------------------------------------------------------------------

initialkey_wave_r =1'b1;

always@(posedgeclk)key_wave_r <=key_wave;

assignflag_neg =(key_wave_r ==1'b1&&key_wave ==1'b0)?1'b1:1'b0;

assignflag_pos =(key_wave_r ==1'b0&&key_wave ==1'b1)?1'b1:1'b0;

//--------------------------------------------------------------------------------------------  

 

digital_clock_ctrl模块的设计思想:首先根据外部的调整脉冲,确定工作状态。

 

reg[1:0]  state_adjust;// 0 : 正常模式 1:小时调整 2 :分钟调整 3 :秒调整


// 切换调整模式和正常模式

 always@(posedgeclk)begin

   if(rst_n ==1'b0)

     state_adjust <=2'b00;

   else

     if(key_adjust_flag ==1'b1)

       state_adjust <=state_adjust +1'b1;  // 0-3无限循环

     else

       state_adjust <=state_adjust;

 end

 


根据基本逻辑、工作状态和外部加减脉冲产生24小时进制的时分秒。

// 1秒钟计时 // 只有正常模式才开始计时

   always@(posedgeclk)begin

   if(rst_n ==1'b0)

     cnt <=26'd0;

   else

     if(cnt <T_1s -1'b1 &&state_adjust ==2'd0)

       cnt <=cnt +1'b1;

     else

         cnt <=26'd0;

 end

 

// 秒计时 

// 在秒调整模式中,加和减按键做对应的工作。

// 在正常模式,正常计时

 always@(posedgeclk)begin

   if(rst_n ==1'b0)

     sec <=6'd50;

   else

     if(state_adjust ==2'd3)

       if(key_add_flag ==1'b1)

         if(sec <6'd59)

           sec <=sec +1'b1;

         else

           sec <=6'd0;

       else

         if(key_sub_flag ==1'b1)

           if(sec >6'd0)

             sec <=sec -1'b1;

           else

             sec <=6'd59;

         else

           sec <=sec;

     else

       if(cnt ==T_1s -1'b1)

         if(sec <6'd59)

           sec <=sec +1'b1;

         else

           sec <=6'd0;

       else

         sec <=sec;

end    

 

 

24小时进制和12小时进制在外部按键按下时切换;分和秒的显示没有改变,小时的显示需要调整。24小时制时,正常显示;12小时制时,时大于11时,需要减去12;并且利用led2进行表是为上午还是下午。

//根据显示模式,调整小时的显示

   always@*begin

   if(state ==1'b0)

     hour_adjust =hour;

   else

     if(hour >6'd11)

       hour_adjust =hour -6'd12;

     else

       hour_adjust =hour;

 end

//根据显示模式和小时值,计算是上午还是下午

 always@*begin

   if(state ==1'b0)

     led2 =1'b0;

   else

     if(hour >6'd11)

       led2 =1'b0;

     else

       led2 =1'b1;

 end

 

 

    如果在调整模式中,启动一个一秒钟的计时器。

 

// 处于调整模式时,开始计时一秒钟

 always@(posedgeclk)begin

   if(rst_n ==1'b0)

     flash_cnt <=26'd0;

   else

     if(state_adjust ==2'd0)

       flash_cnt <=26'd0;

     else

       if(flash_cnt <T_1s -1'b1)

         flash_cnt <=flash_cnt +1'b1;

       else

         flash_cnt <=26'd0;

 end

 

 

    分钟和小时类似,在这里不在赘述。

 

在正常模式下将需要显示的时、分、秒的十位和个位计算出来。在对应的调整模式下,需要前半秒输出对应的数字,后半秒输出全F。在数码管驱动中,当输入正常数字0~9显示数字,当输入F时数码管熄灭,此时数码管就闪烁起来了。

 

//计算得出小时、分钟、秒的个位和十位  

always@(posedgeclk)hour_shi <=(state_adjust ==2'd1&&flash_cnt >T_1s/2)?4'hf:hour_adjust/10;  

always@(posedgeclk)hour_ge <=(state_adjust ==2'd1&&flash_cnt >T_1s/2)?4'hf:hour_adjust%10;  

always@(posedgeclk)min_shi <=(state_adjust ==2'd2&&flash_cnt >T_1s/2)?4'hf:min/10;  

always@(posedgeclk)min_ge <=(state_adjust ==2'd2&&flash_cnt >T_1s/2)?4'hf:min%10;  

always@(posedgeclk)sec_shi <=(state_adjust ==2'd3&&flash_cnt >T_1s/2)?4'hf:sec/10;  

always@(posedgeclk)sec_ge <=(state_adjust ==2'd3&&flash_cnt >T_1s/2)?4'hf:sec%10;

 

 

 

所有的逻辑在复位时,可以给予各种值,下板时,通过按下复位,可以让数字钟从自己想要的时间开始运行。

 

以上即为digital_clock_ctrl模块的设计思想;

 

七段数码管为普通六位一体的共阳极数码,采用动态驱动的方式,在此不再赘述。


    下板后(下板成功,按下复位并释放,复位的时间设置为上午11时59分50秒),我们就可以看到数字钟的运行情况。    
    当然我们也可以使用按键进行调节到我们想要的任何时间点。

    下板后,led1点亮(24小时制),经过10秒后,可以看到12时0分0秒。

 

 

 

 

 

 

    按下复位后,立刻按下切换显示模式。此时led1熄灭(12小时制),led2点亮(上午)。经过10秒后,可以看到0时0分0秒,led2熄灭(下午)。

 

 


  下板后,演示视频(链接)如下:
https://www.bilibili.com/video/BV1FT4y1x7RQ/?vd_source=b5405faeab8632f02533bcbfc5e52e55

     本设计所有内容(设计代码、设计工程)链接为:

     

链接:https://pan.baidu.com/s/1Bo6GK1bm1vDXfahwZusKVg 

提取码:i9xj

 

  本篇内容中有部分资源来源于网络,如有侵权,请联系作者。

 

  如果您觉得本公众号还不错的话,可以推给身边的朋友们,感谢并祝好!

与基于FPGA的数字钟设计---第三版相似的内容:

基于FPGA的数字钟设计---第三版

欢迎各位朋友关注“郝旭帅电子设计团队”,本篇为各位朋友介绍基于FPGA的数字钟设计 第三版。 功能说明: 1. 在数码管上面显示时分秒(共计六个数码管,前两个显示小时;中间两个显示分钟;最后两个显示秒)。 2. 利用按键可以切换24/12小时制(默认24小时制)。 3. led1的亮灭表示24小时制

基于FPGA的计算器设计---第一版

欢迎各位朋友关注“郝旭帅电子设计团队”,本篇为各位朋友介绍基于FPGA的计算器设计 第一版。 功能说明: 1. 计算器的显示屏幕为数码管。 2. 4x4矩阵键盘作为计算器的输入设备。 3. 计算任意两位正整数的加减乘除。 4. 当减法结果出现负数时(一个小的数字减去一个大的数字),数码管需要显示负数

基于FPGA的4x4矩阵键盘驱动设计---第一版

欢迎各位朋友关注“郝旭帅电子设计团队”,本篇为各位朋友介绍基于FPGA的4x4矩阵键盘驱动设计 第一版 功能说明: 1. 驱动4x4矩阵键盘:按下任意一个按键,解析出对应按键信息,并给出标志 使用平台:纯代码形式 使用语言:Verilog HDL 作者QQ:746833924 说明:本篇设计中不涉及

基于FPGA的电子琴设计(按键和蜂鸣器)----第一版

欢迎各位朋友关注“郝旭帅电子设计团队”,本篇为各位朋友介绍基于FPGA的电子琴设计(按键和蜂鸣器) 第一版。 功能说明: 外部输入七个按键,分别对应音符的“1、2、3、4、5、6、7”,唱作do、re、mi、fa、sol、la、si。当某个按键按下时,蜂鸣器发出对应的声音 1. 默认发出0.2秒(可

基于FPGA的贪吃蛇游戏 之代码解析

基于FPGA的贪吃蛇游戏 之代码解析 1. 代码结构 代码结构包含7格.v文件。 下面依次解析。 2. 代码解析 (1) seg_display.v 数码管的译码模块是最熟悉,最简单的模块了。这里是共阳极的数码管,用case语句编码即可。从上图可以看到,这个模块被例化了3次,分别驱动3个数码管显示,

ZynqMP PL固件通过U-BOOT从指定位置加载FPGA BIT

原因 PL固件可能经常修改,而BOOT.BIN和文件系统、内核实际上基本不会变,在一个平台上可以用同一份。如果每次修改都要重新打包PL 固件到BOOT.BIN,操作起来非常麻烦。所以希望PL 的固件可以直接从指定位置加载。典型的可以从SD卡的FAT32分区加载。 https://xilinx-wik

基于 Three.js 的 3D 模型加载优化

作为一个3D的项目,从用户打开页面到最终模型的渲染加载的时间也会比普通的H5项目要更长一些,从而造成大量的用户流失。为了提升首屏加载的转化率,需要尽可能的降低loading的时间。这里就分享一些我们在模型加载优化方面的心得。

基于MindSpore实现BERT对话情绪识别

本文分享自华为云社区《【昇思25天学习打卡营打卡指南-第二十四天】基于 MindSpore 实现 BERT 对话情绪识别》,作者:JeffDing。 模型简介 BERT全称是来自变换器的双向编码器表征量(Bidirectional Encoder Representations from Trans

基于 Vagrant 手动部署多个 Redis Server

环境准备 宿主机环境:Windows 10 虚拟机环境:Vagrant + VirtualBox Vagrantfile 配置 首先,我们需要编写一个 Vagrantfile 来定义我们的虚拟机配置。假设已经在 D:\Vagrant\redis 目录下创建了一个 Vagrantfile,其内容如下:

基于EF Core存储的Serilog持久化服务

前言 Serilog是 .NET 上的一个原生结构化高性能日志库,这个库能实现一些比内置库更高度的定制。日志持久化是其中一个非常重要的功能,生产环境通常很难挂接调试器或者某些bug的触发条件很奇怪。为了在脱离调试环境的情况下尽可能保留更多线索来辅助解决生产问题,持久化的日志就显得很重要了。目前Ser