一、项目需求
- 使用扩展板上的12颗彩灯对应于12个小时
- 核心板上的FPGA产生时钟,在OLED显示评上通过模拟或者数字的方式显示当前的时间 - 小时、分、秒
- 将“小时”的信息通过12颗彩灯来显示,效果自行设计
- 具有定时的功能,通过扩展板上的按键设置时间,到该时间点即(彩灯闪烁 + 音频播放),持续5秒钟时间
- 音频播放通过扩展板上的蜂鸣器来实现
二、完成的功能
首先按下“RUN”键会显示初始页面,是一些基本信息。
“K1”键可以调节不同的模式,总共有八种模式,分别为:
1.初始界面(基本信息)
2.显示当前时间,闹钟时间,倒计时(如下图)
3.调节当前时间的“时”
4.调节当前时间的“分”
5.调节当前时间的“秒”
6.调节闹钟时间的“时”(如下图)
7.调节闹钟时间的“分”
8.调节闹钟时间的“秒”
上述对时间的调节均是通过“K2”键来实现,12个灯板会对应当前时间的“时”。
设定好当前时间与闹钟时间后,需要回到模式2,然后到了设定的时间,蜂鸣器就会播放音乐,灯板会闪亮(需按“K2”键取消)。
如下图,我设置了闹钟02:37:33,到时间后就会触发一系列反应。
三、实现思路
为了实现以上功能,主要有以下几个关键模块:
时钟模块 (time_cal.v):计算当前小时、分钟和秒。
时间差值计算 (disparity_time.v):计算倒计时。
显示模块 (oled_chinese.v):控制 OLED 上的时间显示,包括数字和模拟显示模式。
LED 灯控制 (ws2812.v):通过 WS2812 控制 LED 环,对当前时间进行运行渲染。
音频控制 (beeper_ctrl.v, beeper.v):在预设时间到达时提醒,并通过按键停止。
按键处理 (debounce.v, key_debounce.v):实现按键输入去振,磁带按键的出发信号。
模式控制系统 (key1_function.v,key2_function.v):OLED显示模式切换(8种模式),调节时间与闹钟。
流程图
功能框图
FPGA资源占用报告
四、实现过程
1. 时钟模块实现
时钟模块 time_cal.v 用于生成时间,以下是其主要代码:
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
second <= 6'd0;
minute <= 6'd0;
hour <= 6'd0;
end
else if (second == 6'd59)
begin
second <= 6'd0;
if (minute == 6'd59)
begin
minute <= 6'd0;
if (hour == 6'd23)
hour <= 6'd0;
else
hour <= hour + 1'b1;
end
else
minute <= minute + 1'b1;
end
else
second <= second + 1'b1;
end
2. OLED 显示实现
oled_chinese.v 控制 OLED 屏幕上的时间显示,以下是一个基本样式代码:
always @(posedge clk)
begin
if(display_mode == 0)
oled_data <= {hour[3:0], minute[3:0], second[3:0]};
else
oled_data <= custom_graphic; // 模拟表盘显示
end
3. LED 环控制
ws2812.v 控制 WS2812 LED 灯,对应小时以 LED 渲染出来:
always @(posedge clk or negedge rst)
begin
if(!rst)
led_color <= 24'h000000;
else case(hour)
1: led_color <= 24'hFF0000; // 1点 红色
2: led_color <= 24'h00FF00; // 2点 绿色
3: led_color <= 24'h0000FF; // 3点 蓝色
...
default: led_color <= 24'hFFFFFF; // 默认 白色
endcase
end
4. 音频控制
beeper_ctrl.v 控制音频,进行进一步触发。当时间到达时,启动音频展示:
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
beeper_en <= 1'b0;
cnt_5s <= 0;
end
else if(beeper_start)
beeper_en <= 1'b1;
else if(beeper_stop || cnt_5s == MAX_5s - 1'b1)
beeper_en <= 1'b0;
else if(beeper_en)
cnt_5s <= cnt_5s + 1'b1;
end
五、遇到的主要难题
1.由于 WS2812 LED 需要非常精确的时间控制,刚开始灯光无法正常点亮。后来通过使用 状态机 进行数据发送,并借助工具调试时序,才让 LED 按预期显示颜色。
2.按键有抖动,导致按一下可能被识别为多次按键。为了解决这个问题,增加了 按键去抖动 处理,让按键信号更加稳定。
3.由于 FPGA 资源有限,最开始代码运行时 FPGA 无法全部支持。后来通过 优化代码,减少不必要的存储和计算,成功让系统在 FPGA 上正常运行。
六、未来的改进建议
1.通过 蓝牙模块(如 HC-05),让手机端可以远程设定闹钟时间,增强用户体验。
2.通过 I²C 接口添加 温湿度传感器,让 OLED 显示实时环境信息