基于FPGA的按键提示音设计
1. 设计要求
按键按下,蜂鸣器要“叮”一声。
2. 设计分析
该设计方案采用野火征途MiNi FPGA开发板(intel-Cyclone IV -EP4CE10F17C8)实现,利用开发板的按键做输入设备,无源蜂鸣器做输出设备。硬件连接图如下图所示:

开发板晶振为50MHz,提供系统时钟信号,复位按键按下为低电平,弹起为高电平。无源蜂鸣器采用10KHz的方便驱动,每次发出声音的时间为0.1s。
(1)顶层模块设计

端口及其含义:
- clk_50M:系统时钟,50MHz;
- rst_n: 系统复位信号,低电平有效;
- key_in: 按键输入信号
- beep: 蜂鸣器驱动信号。
(2)架构设计

根据系统功能描述,该系统可由按键消抖模块、边沿检测模块和蜂鸣器驱动模块组成,按键消抖模块负责对按键进行消抖操作,当边沿检测模块检测到按键按下时,会产出一个周期高电平的脉冲信号key_flag,利用该脉冲产出一个长度为0.1s方波信号,驱动蜂鸣器发声。
3. 设计实现
(1)按键消抖模块的设计与实现
1 module key_filter(
2 input wire clk,
3 input wire rst_n,
4 input wire key_n,
5
6 output reg key_out
7 );
8
9 localparam IDLE = 4'b0001;
10 localparam FILTER0 = 4'b0010;
11 localparam DOWN = 4'b0100;
12 localparam FILTER1 = 4'b1000;
13
14 parameter T_10MS = 19'd500_000;
15
16 reg key_n_r;
17 reg key_n_rr;
18 reg [3:0] c_state;
19 reg [3:0] n_state;
20 reg [18:0] cnt;
21
22 always@(posedge clk)begin
23 key_n_r <= key_n;
24 key_n_rr <= key_n_r;
25 end
26
27 always@(posedge clk or negedge rst_n)begin
28 if(rst_n == 1'b0)
29 c_state <= IDLE;
30 else
31 c_state <= n_state;
32 end
33
34 always@(*)begin
35 case(c_state)
36 IDLE : begin
37 if(key_n_rr == 1'b0)
38 n_state = FILTER0;
39 else
40 n_state = IDLE;
41 end
42
43 FILTER0 : begin
44 if(key_n_rr == 1'b1)
45 n_state = IDLE;
46 else
47 if(cnt < T_10MS - 1'b1)
48 n_state = FILTER0;
49 else
50 n_state = DOWN;
51 end
52
53 DOWN : begin
54 if(key_n_rr == 1'b0)
55 n_state = DOWN;
56 else
57 n_state = FILTER1;
58 end
59
60 FILTER1 : begin
61 if(key_n_rr == 1'b0)
62 n_state = DOWN;
63 else
64 if(cnt < T_10MS - 1'b1)
65 n_state = FILTER1;
66 else
67 n_state = IDLE;
68 end
69 default : n_state = IDLE;
70 endcase
71 end
72
73 always@(posedge clk or negedge rst_n)begin
74 if(rst_n == 1'b0)
75 cnt <= 19'd0;
76 else begin
77 case(c_state)
78 IDLE : cnt <= 19'd0;
79
80 FILTER0 : begin
81 if(key_n_rr == 1'b1)
82 cnt <= 19'd0;
83 else
84 if(cnt < T_10MS - 1'b1)
85 cnt <= cnt + 1'b1;
86 else
87 cnt <= 19'd0;
88 end
89
90 DOWN : cnt <= 19'd0;
91
92 FILTER1 : begin
93 if(key_n_rr == 1'b0)
94 cnt <= 19'd0;
95 else
96 if(cnt < T_10MS - 1'b1)
97 cnt <= cnt + 1'b1;
98 else
99 cnt <= 19'd0;
100 end
101 default : cnt <= 19'd0;
102 endcase
103 end
104 end
105
106 always@(posedge clk or negedge rst_n)begin
107 if(rst_n == 1'b0)
108 key_out <= 1'b1;
109 else
110 if(c_state == DOWN || c_state == FILTER1)
111 key_out <= 1'b0;
112 else
113 key_out <= 1'b1;
114 end
115
116 endmodule
(2)边沿检测模块的设计与实现
1 module edge_check(
2 input wire clk_50M,
3 input wire rst_n,
4 input wire key_out,
5
6 output wire key_flag
7 );
8
9 reg key_out_reg;
10
11 always@(posedge clk_50M or negedge rst_n)begin
12 if(rst_n == 1'b0)
13 key_out_reg <= 1'b0;
14 else
15 key_out_reg <= key_out;
16 end
17
18 assign key_flag = key_out_reg && (~key_out);
19
20 endmodule
(3)蜂鸣器驱动模块的设计与实现
1 module beep_drive(
2 input wire clk_50M,
3 input wire rst_n,
4 input wire key_flag,
5
6 output wire beep
7 );
8
9 parameter FREQ = 10_000;
10 parameter HALF = 50_000_000/(2*FREQ);
11 parameter T_100MS = 5_000_000;
12
13 reg [25:0] cnt;
14 reg wave_10k;
15 reg [25:0] count;
16 wire valid;
17
18 always@(posedge clk_50M or negedge rst_n)begin
19 if(rst_n == 1'b0)
20 cnt <= 26'd0;
21 else
22 if(cnt < HALF - 1'b1)
23 cnt <= cnt + 1'b1;
24 else
25 cnt <= 26'd0;
26 end
27
28 always@(posedge clk_50M or negedge rst_n)begin
29 if(rst_n == 1'b0)
30 wave_10k <= 1'b0;
31 else
32 if(cnt == HALF -1'b1)
33 wave_10k <= ~wave_10k;
34 else
35 wave_10k <= wave_10k;
36 end
37
38 always@(posedge clk_50M or negedge rst_n)begin
39 if(rst_n == 1'b0)
40 count <= T_100MS;
41 else
42 if(key_flag == 1'b1)
43 count <= 26'd0;
44 else if(count < T_100MS)
45 count <= count + 1'b1;
46 else
47 count <= count;
48 end
49
50 assign valid = (count < T_100MS) ? 1'b1 : 1'b0;
51
52 assign beep = wave_10k && valid;
53
54 endmodule
1 `timescale 1ns/1ps
2
3 module beep_drive_tb();
4 reg clk_50M;
5 reg rst_n;
6 reg key_flag;
7
8 wire beep;
9
10 defparam beep_drive_inst.T_100MS = 500;
11 defparam beep_drive_inst.FREQ = 1000_000;
12
13 beep_drive beep_drive_inst(
14 .clk_50M (clk_50M),
15 .rst_n (rst_n),
16 .key_flag (key_flag),
17
18 .beep (beep)
19 );
20
21 initial clk_50M = 1'b0;
22 always #10 clk_50M = ~clk_50M;
23
24 initial begin
25 rst_n = 1'b0; key_flag = 1'b0;
26 #201;
27 rst_n = 1'b1;
28 repeat(5)begin
29 @(posedge clk_50M); #2;
30 key_flag = 1'b1;
31 @(posedge clk_50M); #2;
32 key_flag = 1'b0;
33 #(20*1000);
34 end
35 #500;$stop;
36 end
37
38 endmodule

参考文献:
(1)陪您一起学习FPGA-郝旭帅团队_哔哩哔哩_bilibili;
基于FPGA的按键提示音设计的更多相关文章
- 基于FPGA的按键扫描程序
最近在学习FPGA,就试着写了个按键扫描的程序.虽说有过基于单片机的按键扫描处理经验,对于按键的处理还是有一些概念.但是单片机程序的编写通常都采用C写,也有用汇编,而FPGA却是采用VHDL或者Ver ...
- 基于FPGA的XPT2046触摸控制器设计
基于FPGA的XPT2046触摸控制器设计 小梅哥编写,未经许可,文章内容和所涉及代码不得用于其他商业销售的板卡 本实例所涉及代码均可通过向 xiaomeige_fpga@foxmail.com 发 ...
- 基于FPGA的SPI FLASH控制器设计
1.SPI FLASH的基本特征 本文实现用FPGA来设计SPI FLASH,FLASH型号为W25Q128BV.支持3种通信方式,SPI.Dual SPI和Quad SPI.FLASH的存储单元无法 ...
- 012 基于FPGA的网口通信实例设计【转载】
一.网口通信设计分类 通过上面其他章节的介绍,网口千兆通信,可以使用TCP或者UDP协议,可以外挂PHY片或者不挂PHY片,总结下来就有下面几种方式完成通信: 图8‑17基于FPGA的网口通信实例设计 ...
- 基于FPGA的1553B通信模块的设计(转)
reference:http://www.21ic.com/app/eda/201808/798483.htm https://www.milstd1553.com/ [导读] 摘 要: 提出一种将F ...
- verilog实验2:基于FPGA的59秒计时器设计
一.实验任务 利用四个数码管显示59秒计时器. 二.代码实现 将开发板的48M晶振分频出1M,然后计数器累加,将计数器结果显示在数码管上.低位逢十进一,第二位逢五进一,依次构成59秒计时器. 部分代码 ...
- 基于FPGA的Cordic算法实现
CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数.双曲线.指数.对数的 ...
- 基于FPGA的HDMI显示设计(三)
上一篇:基于FPGA的VGA显示设计(二) 10月10日 ~ 20日期间实习,令我万万没想到的是实习题目是 “便携式高清电视显示屏测试系统原型设计” 也就是 “基于FPGA的视频显示”. 实习要求用 ...
- 优化基于FPGA的深度卷积神经网络的加速器设计
英文论文链接:http://cadlab.cs.ucla.edu/~cong/slides/fpga2015_chen.pdf 翻译:卜居 转载请注明出处:http://blog.csdn.net/k ...
- 基于FPGA的DDS设计(一)
最近在学习基于FPGA的DDS设计,借此机会把学习过程记录下来,当作自己的学习笔记也希望能够帮助到学习DDS的小伙伴. DDS(Direct Digital Synthesizer)直接数字合成器,这 ...
随机推荐
- 安装程序无法创建新的系统分区,也无法定位现有系统分区_安装win7在固态硬盘解决
在安装Windows7时,想必有很多人都安碰到这样的情况吧!在安装界面里选择安装时,却出现"安装程序无法创建新的系统分区,也无法定位现有系统分区" 如下图: 方法/步骤 进入win ...
- Spring 概述和依赖注入(DI)
Spring概述 Spring框架是一个轻量级的企业级开发的一站式解决方案 Spring框架主要提供Ioc容器.AOP.数据访问.WEB开发.消息.测试等相关技术的支持 每一个被Spring管理的Ja ...
- Oracle中复杂数据处理
利用聚合函数统计数据 求最大值-max() max()可应用数值型和字符型和日期型(实质也是数值型) select max(employee_age) max_age from employees m ...
- 音频克隆阿里版-CosyVoice
前面介绍过了音频克隆 IndexTTS:https://www.cnblogs.com/cj8988/p/18973016 ComfyUI_IndexTTS: https://www.cnblogs. ...
- java slider
简介 简单 code /* * @Author: your name * @Date: 2020-11-05 10:21:52 * @LastEditTime: 2020-11-05 10:45:16 ...
- 使用字符串创建java 对象
简介 RT code String s = "java.util.Random"; Object m = Class.forName(s).newInstance();
- 通过ETL工具快速实现单据同步
ETLCloud介绍 ETLCloud是一款旨在解决企业数据集成挑战的最新一代平台,它集成了离线数据集成ETL.ELT.CDC实时数据集成.编排调度和数据服务API等功能,形成了一体化的DataOps ...
- SciTech-EECS-Redis for AI: Redis 8为 Vector Similarity (向量相似性) 推出新的数据结构
SciTech-EECS-Redis: VD(Vector Database, 向量数据库): VD对由 Generative AI (生成式人工智能) 驱动的应用程序至关重要. VD可以检索&quo ...
- SciTech-BigDataAI-ImageProcessing-Numerical Analysis-Useful Operations-Color Image Channels with OpenCV+NumPy+Pandas
Links: https://pyimagesearch.com/2021/01/23/splitting-and-merging-channels-with-opencv/ OpenCV Offic ...
- Docker常用命令大全--九五小庞
Docker常用命令大全,请看菜鸟教程 Docker 命令大全 | 菜鸟教程 (runoob.com)