2025寒假练 - 基于iCE40UP5K的FPGA学习平台实现可定时的音乐时钟
该项目使用了基于iCE40UP5K的FPGA学习平台,实现了可定时的音乐时钟的设计,它的主要功能为:具有定时的功能,通过扩展板上的按键设置时间,到该时间点即(彩灯闪烁 + 音频播放),持续5秒钟时间。
标签
嵌入式系统
FPGA
数字逻辑
显示
李金阳
更新2025-03-24
北京理工大学
21

1.项目介绍

  • 可定时的音乐时钟
    1. 使用扩展板上的12颗彩灯对应于12个小时
    2. 核心板上的FPGA产生时钟,在OLED显示屏上通过模拟或者数字的方式显示当前的时间 - 小时、分、秒
    3. 将“小时”的信息通过12颗彩灯来显示,效果自行设计
    4. 具有定时的功能,通过扩展板上的按键设置时间,到该时间点即(彩灯闪烁 + 音频播放),持续5秒钟时间
    5. 音频播放通过扩展板上的蜂鸣器来实现

2. 硬件介绍

  • 核心硬件
    • FPGA开发板iCE40UP5K主控芯片,运行Verilog逻辑,驱动外设。基于Lattice的ICE40UP5K FPGA,板载LPC11U35下载器,可以通过USB-C接口进行FPGA的配置,支持在ICE40UP5K上对RISC-V软核的移植以及开源的FPGA开发工具链,板上RGB三色LED灯用于简单的调试,总计28个IO用于扩展使用。
    • OLED 128x64屏幕:显示实时时间(格式HH:MM:SS)和闹钟设置。
    • WS2812 RGB LED灯带:12颗LED灯,每颗对应1小时,动态指示当前时间。
  • 外设模块
    • 蜂鸣器:报警时播放600Hz提示音(通过PWM控制)。
    • 按键模块:设置当前时间和闹钟(需自行扩展按键输入逻辑)。

3. 方案框图与设计思路

系统框图

设计思路

  1. 时间管理
    • FPGA内部计数器以12MHz生成1秒基准信号,累加时分秒(time1寄存器)。
    • 支持按键修改time1和闹钟时间time_alarm(需扩展按键模块)。
  2. OLED显示
    • 状态机控制屏幕初始化、字符和汉字渲染(如“时”、“分”、“秒”)。
    • 通过SPI协议发送命令和数据,分时刷新显示内容。
  3. LED指示
    • 12颗WS2812 LED灯带,当前小时对应LED高亮(如3点→第3颗亮绿色)。
    • 报警时所有LED切换为红绿交替闪烁模式。
  4. 报警逻辑
    • time1达到time_alarm时,触发enable信号,启动LED闪烁和蜂鸣器鸣响,持续5秒。

4. 软件流程图与关键代码

流程图

关键代码解释

  1. 精确的24小时计时器,每秒更新一次时间值,并具备复位初始化功能。同时,通过状态机和OLED控制信号,可能用于驱动显示设备(如OLED屏幕)的时间展示
    always @ (posedge clk or negedge rst_n) begin
    if(!rst_n) begin
    cnt_main <= 1'b0; cnt_init <= 1'b0; cnt_scan <= 1'b0; cnt_write <= 1'b0;cnt_chinese <= 1'b0;
    y_p <= 1'b0; x_ph <= 1'b0; x_pl <= 1'b0;
    num <= 1'b0; char <= 1'b0; char_reg <= 1'b0;
    num_delay <= 16'd5; cnt_delay <= 1'b0; cnt <= 1'b0;
    oled_csn <= HIGH; oled_rst <= HIGH; oled_dcn <= CMD; oled_clk <= HIGH; oled_dat <= LOW;
    state <= IDLE; state_back <= IDLE;
    end else begin
    time_cnt <= time_cnt + 1;
    if (time_cnt == 26'd11_999_999) begin
    time_cnt <= 26'b0;
    if (time1[5:0] == 6'b111011) begin
    time1[5:0] <= 6'b0;
    if (time1[11:6] == 6'b111011) begin
    time1[11:6] <= 6'b0;
    if (time1[17:12] == 6'b010111) begin
    time1[17:12] <= 6'b0;
    end else begin
    time1[17:12] <= time1[17:12] + 1;
    end
    end else begin
    time1[11:6] <= time1[11:6] + 1;
    end
    end else begin
    time1[5:0] <= time1[5:0] + 1;
    end
    end
  2. 灯圈旋转
    always@(posedge clk or negedge rst ) begin
    if(!rst)begin
    cnt_time<=24'b0;
    ledcolor1<=LED_1;
    ledcolor2<=LED_2;
    ledcolor3<=LED_3;
    ledcolor4<=LED_4;
    ledcolor5<=LED_5;
    ledcolor6<=LED_6;
    end
    else if(cnt_time == cnt_time_max - 1'b1)begin
    cnt_time<=24'b0;
    ledcolor1<=ledcolor6;
    ledcolor2<=ledcolor1;
    ledcolor3<=ledcolor2;
    ledcolor4<=ledcolor3;
    ledcolor5<=ledcolor4;
    ledcolor6<=ledcolor5;
    end
    else
    cnt_time<=cnt_time+1'b1;
    end

3.蜂鸣器

always @(posedge clk )begin

if (cnt < 20000)
cnt <= cnt + 1;
else
cnt <= 0;

if (enable) begin
beep <= (cnt < 10000) ? 1'b0 : 1'b1;
end else begin
beep <= 1'b0;
end
end

5. 功能展示图及说明

  • OLED显示效果
    • 主界面:12:34:56 时 分 秒
    • 闹钟界面:Alarm: 07:30(显示在屏幕下半部分)
  • LED指示效果
    • 正常模式:第3颗LED亮绿色(表示3点)。
    • 报警模式:所有LED红绿交替闪烁。
  • 蜂鸣器报警:持续5秒的600Hz蜂鸣声。

6. 遇到的难题与解决方法

  1. 时间同步问题
    • 问题:按键调整时间后,OLED刷新不同步。
    • 解决:添加状态机锁存按键输入,仅在显示刷新间隙更新时间数据。
  2. WS2812时序控制
    • 问题:LED颜色数据发送时序误差导致显示错乱。
    • 解决:精确计算高低电平时间(T0H=400ns, T1H=800ns)。
  3. 汉字点阵对齐
    • 问题:16x16汉字显示错位。
    • 解决:重新设计点阵数据,分两次写入上半部和下半部(CHINESE状态分38步完成)。1407de04440e75bcc272c4887ef67ca.jpg8c315f68b97674acf505b083c57a7b9.jpg

7.功能展示图及说明

7739ad309333bda12d19efba6cfa16b.jpg0979d1d3d16a2296a9e646fab836cb5.jpg

未到达15秒时无变化,到达15秒后蜂鸣器响起同时彩灯旋转,5秒后停止。

8. 心得体会与建议

  • 收获
    • 掌握了FPGA驱动OLED和WS2812的协议细节(如SPI时序、WS2812数据格式)。
    • 强化了状态机设计和硬件时序调试能力。
  • 建议
    • 希望多一些实际的教程,同时可以把有用的资料整合起来,找起来比较费劲,尤其是对刚入门的人群来说,并且电子森林有些和硬禾学堂不互通的内容。

本项目通过FPGA实现了高精度的定时音乐时钟,结合OLED信息显示、动态LED灯光和蜂鸣器提示,体现了硬件逻辑设计的高效性。未来可进一步扩展为智能家居控制终端,支持更多传感器和通信协议。

image.pngimage.pngimage.png

附件下载
OLED.zip
团队介绍
个人
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号