FPGA电子时钟设计

1.设计目标

- 实现24小时制数字时钟的基本计时功能(时:分:秒)

- 通过8位数码管显示时间,格式为 HH.MM.SS

- 支持按键调整时间(秒、分、时分别可调)

- 拓展:本设计实现闹钟功能,可设置闹钟时间并在指定时间触发蜂鸣器报警

2.开发流程

2.1开发环境

| 目标器件 | EP4CE10F17C8 (Altera Cyclone IV) |

| 开发工具 | Quartus II 13.0 |

| 系统时钟 | 50MHz晶振 |

| 编程语言 | Verilog HDL |

2.2架构设计

为了提供一种最简单直观的显示,开发板上提供了一个7段8位共阳极数码管电路,为了减少对FPGA引脚资源的占用,开发板上的数码管采用串行移位寄存器芯片将串行数据转化为16位并行数据后进行驱动。Cyclone IV E通过3根数据线,连接到两片级联的串行移位器芯片74HC595上,再由74HC595将每次16位串行的数据转化为16位并行的数据,分别用以驱动7段8位数码管的段选和位选。

top顶层模块,负责各子模块的连接与信号分配 (top.v) 

Project_Segled2 数字时钟核心模块,包含计时、显示、按键处理、闹钟等功能( Project_Segled2.v)

HC595_Driver|74HC595移位寄存器驱动,实现串行数据输出(HC595_Driver.v )

2.3顶层IO

module top( input Clk, // 50MHz系统时钟 input Rst_n, // 复位信号(低电平有效) input KEY1, // 模式切换/长按进入闹钟设置 input KEY2, // 数值递增按键 output SH_CP, // 74HC595移位时钟 output ST_CP, // 74HC595锁存时钟 output DS, // 74HC595串行数据 output BEEP // 蜂鸣器输出 ); 

2.4数字时钟核心模块 (Project_Segled2.v)

2.4.1 按键消抖

采用计数器消抖方式,消抖时间约20ms:

parameter DB_CNT_MAX = 20'd100; // 消抖计数最大值 // 两级同步 + 计数消抖 always @(posedge CLK_50M or negedge RST_N) begin     if(!RST_N) begin         k1_sync0 <= 1'b1; k1_sync1 <= 1'b1;     end else begin         k1_sync0 <= FLAG1; k1_sync1 <= k1_sync0;     end end 

设计特点:

- 采用两级触发器同步,防止亚稳态

- 检测高→低电平翻转,产生单周期脉冲

- 支持长按检测(1秒),用于进入闹钟设置模式

2.4.2 计时

基于50MHz时钟进行分频,实现秒、分、时的计时:

// 关键参数 parameter SET_TIME_1S = 'd50_000_000;  // 1秒计数值 parameter SIXTY = 'd60;                 // 60进制 parameter TWENTYFORE = 'd24;            // 24进制 // 1秒定时器 always @ (posedge CLK_50M or negedge RST_N) begin     if(!RST_N)         cnt_1s <= 28'd0;     else if(set_mode != 2'd0)  // 调整模式下暂停         cnt_1s <= 28'd0;     else if(cnt_1s == SET_TIME_1S - 1)         cnt_1s <= 28'd0;     else         cnt_1s <= cnt_1s + 28'b1; end

计时进位逻辑:

- 秒:0-59循环,满60进位

- 分:0-59循环,满60进位

- 时:0-23循环,满24复位

2.4.3 时间调整模式状态机

通过按键切换四种工作模式:

| 模式值 | 模式名称 | 功能描述 |

| 0 | 正常模式 | 时钟正常走时 |

| 1 | 调秒模式 | 秒位闪烁,可调整秒 |

| 2 | 调分模式 | 分位闪烁,可调整分 |

| 3 | 调时模式 | 时位闪烁,可调整时 |

always @(posedge CLK_50M or negedge RST_N) begin     if(!RST_N)         set_mode <= 2'd0;     else if(mode_pulse && !alarm_set_mode && !alarm_triggered)         set_mode <= set_mode + 2'd1;  // 0→1→2→3→0 循环 end

2.4.4 闹钟功能

闹钟设置流程:

- 长按KEY1(1秒)进入闹钟设置模式

- 短按KEY1切换时/分设置位置

- 按KEY2递增当前设置值

- 再次长按KEY1退出设置并使能闹钟

// 闹钟触发检测 always @(posedge CLK_50M or negedge RST_N) begin     if(!RST_N)         alarm_triggered <= 1'b0;     else if(alarm_triggered && (mode_pulse || inc_pulse))         alarm_triggered <= 1'b0;  // 任意按键取消     else if(alarm_enabled && !alarm_set_mode &&             cnt_h == alarm_h && cnt_m == alarm_m && cnt_s == 6'd0)         alarm_triggered <= 1'b1;  // 时间匹配,触发闹钟 end

报时特性:

- 闪烁6次(300ms周期)

- 蜂鸣器间歇发声

2.4.5 数码管显示

采用动态扫描方式驱动8位数码管:

// 显示格式: HH-MM-SS // 位置分配: 7-6-5-4-3-2-1-0 //          时十位-时个位-横线-分十位-分个位-横线-秒十位-秒个位 // 1ms扫描周期 parameter SET_TIME_1MS = 16'd50_000; // 段码查找表(共阴极数码管) parameter SEG_CODE_0 = 8'b1100_0000,           SEG_CODE_1 = 8'b1111_1001,           ...           SEG_CODE_9 = 8'b1001_0000,           SEG_CODE_DASH = 8'b1011_1111;  // 横线"-"

二进制转BCD算法(Double Dabble):

// 将6位二进制数转换为2位BCD for(i = 5; i >= 0; i = i - 1) begin     if (s_ones >= 4'd5) s_ones = s_ones + 4'd3;     if (s_tens >= 4'd5) s_tens = s_tens + 4'd3;     s_tens = {2'b00, s_tens[2:0], s_ones[3]};     s_ones = {2'b00, s_ones[2:0], cnt_s[i]}; end 

2.4.6 蜂鸣器控制

生成约2kHz方波驱动蜂鸣器:

parameter BEEP_FREQ_CNT = 16'd12500;  // 50MHz/12500/2 = 2kHz always @(posedge CLK_50M or negedge RST_N) begin     if(!RST_N)         beep_cnt <= 16'd0;     else if(beep_cnt >= BEEP_FREQ_CNT - 1) begin         beep_cnt <= 16'd0;         beep_tone <= ~beep_tone;     end else         beep_cnt <= beep_cnt + 16'd1; end

2.5 74HC595驱动模块 (HC595_Driver.v)

2.5.1 74HC595芯片简介

74HC595是一款8位串入并出移位寄存器,具有以下特点:

- 串行数据输入,8位并行数据输出

- 具有输出锁存功能

- 可级联扩展

2.5.2 引脚功能

| 引脚 | 名称 | 功能 |

|------|------|------|

| DS | 数据输入 | 串行数据输入端 |

| SH_CP | 移位时钟 | 上升沿移入数据 |

| ST_CP | 锁存时钟 | 上升沿锁存数据到输出 |

2.5.3 驱动时序设计

parameter DATA_WIDTH = 16;  // 16位数据(8位段码 + 8位位选) parameter CNT_MAX = 4;      // 分频系数 // 移位时钟生成 always@(posedge Clk or negedge Rst_n)     if(!Rst_n)         divider_cnt <= 16'd0;     else if(divider_cnt == CNT_MAX)         divider_cnt <= 16'd0;     else         divider_cnt <= divider_cnt + 1'b1; assign sck_pluse = (divider_cnt == CNT_MAX);

2.5.4 时序状态机

case(SHCP_EDGE_CNT)     5'd0: begin SH_CP <= 1'b0; ST_CP <= 1'b1; DS <= r_data[15]; end     5'd1: begin SH_CP <= 1'b1; ST_CP <= 1'b0; end     5'd2: begin SH_CP <= 1'b0; DS <= r_data[14]; end     5'd3: begin SH_CP <= 1'b1; end     // ... 依次移出16位数据     5'd30: begin SH_CP <= 1'b0; DS <= r_data[0]; end     5'd31: begin SH_CP <= 1'b1; end endcase

3 系统功能说明

3.1 操作说明

| 操作 | 按键 | 功能说明 |

|------|------|----------|

| 模式切换 | 短按KEY1 | 正常→调秒→调分→调时→正常 循环 |

| 数值调整 | 按KEY2 | 在调整模式下,递增当前选中位 |

| 进入闹钟设置 | 长按KEY1(1秒) | 进入闹钟时间设置模式 |

| 切换闹钟设置位 | 短按KEY1 | 在闹钟设置模式下切换时/分 |

| 设置闹钟值 | 按KEY2 | 递增闹钟时间 |

| 退出闹钟设置 | 长按KEY1(1秒) | 保存并使能闹钟 |

| 取消闹钟 | 按任意键 | 闹钟响时按任意键停止 |

3.2 状态指示

| 状态 | 显示效果 |

|------|----------|

| 正常计时 | 全部数字稳定显示 |

| 调秒模式 | 秒位闪烁(250ms周期) |

| 调分模式 | 分位闪烁(250ms周期) |

| 调时模式 | 时位闪烁(250ms周期) |

| 闹钟设置 | 被调整位闪烁,秒显示00 |

| 整点报时 | 全部闪烁6次(300ms周期),蜂鸣器间歇响 |

| 闹钟触发 | 全部快速闪烁(125ms周期),蜂鸣器持续响 |

4附录

完整代码如下

https://github.com/acousma-az/FPGA_digital_clock

  

Read more

WIN11必备!QTTabBar中文优化版保姆级安装教程(含常见问题解决)

WIN11效率革命:深度定制你的资源管理器,不止于多标签 如果你和我一样,每天要在Windows的资源管理器里花费大量时间,那你一定对那种反复在层层文件夹中穿梭、找不到上一个窗口的体验深恶痛绝。系统自带的文件管理工具,就像一个功能简陋的毛坯房,勉强能用,但毫无效率与舒适度可言。尤其是升级到WIN11后,虽然界面更现代,但核心的文件管理逻辑依然停留在上个时代,对于追求效率的用户来说,这无疑是一种巨大的生产力损耗。 这篇文章,就是为那些不愿忍受现状,但又不想投入过多精力去学习复杂新软件的WIN10/WIN11用户准备的。我们不讨论那些需要彻底改变操作习惯的“重型”第三方管理器,而是聚焦于一种更优雅、更无感的解决方案:增强你正在使用的资源管理器本身。今天的主角,是一个经过国内开发者精心“魔改”的经典工具——QTTabBar的中文优化版。它就像给你的文件管理器做了一次精装修,保留了熟悉的格局,却赋予了它全新的、高效的能力。接下来,我将带你从零开始,完成这次效率升级,并深入探讨如何根据你的习惯,将它调校成最趁手的工具。 1. 为什么选择增强,而非替换? 在深入安装细节之前,我们有必要先

curobo——CUDA加速的机器人库

curobo——CUDA加速的机器人库

仓库地址:https://github.com/nvlabs/curobo 目录 * 1.关于curobo * 1.1 仓库概述 * 1.2 仓库目录结构 * 1.3 启动文件介绍 * 1.4 配置文件介绍 * 2.curobo安装和部署 * 2.1 curobo本地安装 * 2.2 示例测试 1.关于curobo 1.1 仓库概述 cuRobo(CUDA Accelerated Robot Library)是 NVIDIA 推出的基于 CUDA 加速的机器人算法库,专注于通过并行计算大幅提升机器人相关算法的运行速度。该库提供了一系列高性能的机器人学核心算法,适用于运动规划、轨迹线优化、碰撞检测等关键任务。 * 核心功能

Qwen2.5-7B对话机器人:5分钟微信接入教程,2块钱体验

Qwen2.5-7B对话机器人:5分钟微信接入教程,2块钱体验 引言:为什么选择Qwen2.5做微信群助手? 最近很多做私域运营的朋友都在问:能不能用AI大模型做个智能微信群助手?市面上技术外包动辄报价2万元,自己折腾又卡在环境配置的第三步。今天我要分享的解决方案,只需要5分钟和2块钱,就能让强大的Qwen2.5-7B模型成为你的24小时微信群客服。 Qwen2.5是阿里云最新开源的对话大模型,相比前代有三大优势: 1. 更懂中文:针对中文对话优化,回答更自然 2. 多语言支持:能处理29种语言,国际业务也适用 3. 长对话记忆:支持128K超长上下文,不会"忘记"之前的聊天 最重要的是,通过ZEEKLOG算力平台的预置镜像,我们可以跳过繁琐的环境配置,直接一键部署。下面我就手把手教你如何操作。 1. 准备工作:3件必备物品 在开始之前,你需要准备好: 1. ZEEKLOG账号:注册并完成实名认证(免费) 2. 微信小号:

飞书机器人实战:5分钟搞定图片消息发送(含常见报错解决方案)

飞书机器人实战:5分钟搞定图片消息发送(含常见报错解决方案) 你是否遇到过这样的场景:服务器监控系统捕捉到一个异常峰值,你希望它能自动将一张清晰的图表截图,直接推送到团队的飞书群里,而不是一封冰冷的邮件;或者,你的自动化日报系统生成了精美的数据可视化图片,你希望它能无缝地出现在每日的晨会通知中。对于许多开发者和运维工程师来说,将图片消息集成到自动化流程中,是一个能极大提升信息传达效率和体验的“刚需”。 飞书机器人提供了强大的消息推送能力,但初次接触其图片消息发送功能时,你可能会发现它比预想的要“曲折”一些——它不像发送文本那样直接丢一个图片链接就行,而是需要经过一个“上传-获取密钥-发送”的流程。这个过程里,权限配置、tenant_access_token获取、图片上传格式、image_key的使用,每一步都可能藏着一个小坑。别担心,这篇文章就是为你准备的“避坑指南”。我们将抛开官方文档那略显冰冷的步骤罗列,从一个实战者的角度,带你用大约5分钟的时间,彻底打通从零到一发送飞书图片消息的全链路,并重点剖析那些你可能马上就会遇到的报错及其根因解决方案。我们的目标是:让你看完就能用,用了