在学习过程中,大多教材给的代码只能循环进行do ri mi fa so la xi,不能进行手动控制,于是本文通过边缘检测拓展出了按键控制蜂鸣器。在教程中输入为sys_clk(时钟信号),sys_rst_n(复位信号),key1 key2 key3 key4 ,输出为beef(利用PWM信号控制蜂鸣器进行声音的播放)。

边缘检测介绍:对于信号的边缘变化,可以用一个周期的高电平表示。

边缘检测方法:先延迟一个周期产生信号a,再延迟一个周期产生信号b,最后了,利用(~a)&b即可产生检测信号,该方法在一些项目中十分常用。

边缘检测代码

module cnten(input  wire                         key                        ,input  wire                         sys_clk                    ,input  wire                         sys_rst_n                  ,output wire                         cnt_en
);
reg                                     key_dly1                   ;
reg                                     key_dly2                   ;
//for the key_dly1
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)key_dly1<=1'b0;
elsekey_dly1<=key;
//for the key_dly2
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)key_dly2<=1'b0;
elsekey_dly2<=key_dly1;
assign cnt_en=(~key_dly1)&(key_dly2);
endmodule

将边缘检测代码实例化用于判断key1 key2 key3 key4信号是否处于1-0边缘,若有四个当中有一个处于,则输出高电平cnt_en。即给四个信号分别进行边缘检测实例化后再取"或"即可。

小钢琴代码如下:

module mybeep #(parameter                           DO = 18'd190_839           ,parameter                           RI = 18'd170_067           ,parameter                           MI = 18'd151_514           ,parameter                           FA = 18'd143_265           ,parameter                           SO = 18'd127_550           ,parameter                           LA = 18'd113_635           ,parameter                           XI = 18'd101_214           ,parameter                           TIME_500MS=25'd24_999_999
)
(input  wire                         sys_clk                    ,input  wire                         sys_rst_n                  ,input  wire                         key1                       ,input  wire                         key2                       ,input  wire                         key3                       ,input  wire                         key4                       ,output reg                          beep
);
reg                    [   2:0]         cnt_500ms                  ;
wire                                    cnt_en1                    ;
wire                                    cnt_en2                    ;
wire                                    cnt_en3                    ;
wire                                    cnt_en4                    ;
reg                    [  17:0]         freq_cnt                   ;
reg                    [  17:0]         freq_data                  ;
wire                   [  16:0]         duty_data                  ;
wire                                    cnt_en                     ;
//for the cnt_en1
cnten cnten_inst1(.key                               (key1                      ),.sys_clk                           (sys_clk                   ),.sys_rst_n                         (sys_rst_n                 ),.cnt_en                            (cnt_en1                   )
);
//for the cnt_en2
cnten cnten_inst2(.key                               (key2                      ),.sys_clk                           (sys_clk                   ),.sys_rst_n                         (sys_rst_n                 ),.cnt_en                            (cnt_en2                   )
);
//for the cnt_en3
cnten cnten_inst3(.key                               (key3                      ),.sys_clk                           (sys_clk                   ),.sys_rst_n                         (sys_rst_n                 ),.cnt_en                            (cnt_en3                   )
);
//for the cnt_en4
cnten cnten_inst4(.key                               (key4                      ),.sys_clk                           (sys_clk                   ),.sys_rst_n                         (sys_rst_n                 ),.cnt_en                            (cnt_en4                   )
);
assign cnt_en=cnt_en1 | cnt_en2 | cnt_en3 | cnt_en4;
//for the cnt_500ms
always @(negedge sys_rst_n or posedge sys_clk)
if(sys_rst_n==1'b0)cnt_500ms<=3'd0;
else if(key1==1'b0 && key2==1'b1 && key3==1'b1 && key4==1'b1)cnt_500ms<=3'd0;
else if(key1==1'b1 && key2==1'b0 && key3==1'b1 && key4==1'b1)cnt_500ms<=3'd1;
else if(key1==1'b1 && key2==1'b1 && key3==1'b0 && key4==1'b1)cnt_500ms<=3'd2;
else if(key1==1'b1 && key2==1'b1 && key3==1'b1 && key4==1'b0)cnt_500ms<=3'd3;
elsecnt_500ms<=3'd7;
//for the freq_cnt and freq_data
always @(negedge sys_rst_n or posedge sys_clk)
if(sys_rst_n==1'b0)
beginfreq_cnt<=1'b0;freq_data<=DO+1'b1;
end
else case(cnt_500ms)3'd0:if(freq_cnt==DO || cnt_en==1'b1)beginfreq_cnt<=1'b0;freq_data<=DO+1'b1;endelsebeginfreq_cnt<=freq_cnt+1'b1;freq_data<=DO+1'b1;end3'd1:if(freq_cnt==RI || cnt_en==1'b1)beginfreq_cnt<=1'b0;freq_data<=RI+1'b1;endelsebeginfreq_cnt<=freq_cnt+1'b1;freq_data<=RI+1'b1;end3'd2:if(freq_cnt==MI || cnt_en==1'b1)beginfreq_cnt<=1'b0;freq_data<=MI+1'b1;endelsebeginfreq_cnt<=freq_cnt+1'b1;freq_data<=MI+1'b1;end3'd3:if(freq_cnt==FA || cnt_en==1'b1)beginfreq_cnt<=1'b0;freq_data<=FA+1'b1;endelsebeginfreq_cnt<=freq_cnt+1'b1;freq_data<=FA+1'b1;end3'd4:if(freq_cnt==SO || cnt_en==1'b1)beginfreq_cnt<=1'b0;freq_data<=SO+1'b1;endelsebeginfreq_cnt<=freq_cnt+1'b1;freq_data<=SO+1'b1;end3'd5:if(freq_cnt==LA || cnt_en==1'b1)beginfreq_cnt<=1'b0;freq_data<=LA+1'b1;endelsebeginfreq_cnt<=freq_cnt+1'b1;freq_data<=LA+1'b1;end3'd6:if(freq_cnt==XI || cnt_en==1'b1)beginfreq_cnt<=1'b0;freq_data<=XI+1'b1;endelsebeginfreq_cnt<=freq_cnt+1'b1;freq_data<=XI+1'b1;enddefault:beginfreq_cnt<=1'b0;freq_data<=DO+1'b1;end
endcase
//for the duty_data
assign duty_data=freq_data>>1'b1;
//for the beep
always @(negedge sys_rst_n or posedge sys_clk)
if(sys_rst_n==1'b0)beep<=1'b0;
else if(freq_cnt<duty_data)beep<=1'b0;
elsebeep<=1'b1;
endmodule

综合出来的电路图如下:

状态转移图如下:

由于作者十分自信,没有进行仿真检验,直接上板验证成功:

FPGA小钢琴制作(边缘检测的应用)相关推荐

  1. 前端制作有趣的小钢琴

    这是小钢琴的链接地址http://kiss-rebounds.gitee.io/interesting-piano/ 如上图所示,这就是小钢琴的界面 在第一个文本框输入数字可以改变钢琴的音色(默认是0 ...

  2. 剧场小钢琴 – Performance Samples River Piano Kontakt

    Performance Samples River Piano Kontakt | 2GB 大厅里录制的里弗钢琴是一个集中在心律不齐纹理上的大型钢琴库,从多八度音阶重复的并奏到保持加权的和弦波和颤音, ...

  3. 基于FPGA的实时图像边缘检测系统设计(上)

    今天给大侠带来基于FPGA的实时图像边缘检测系统设计,由于篇幅较长,分三篇.今天带来第一篇,上篇,话不多说,上货. 导读 随着科学技术的高速发展,FPGA在系统结构上为数字图像处理带来了新的契机.图像 ...

  4. 基于busybox的Linux小系统制作 (initrd)

    我们有时候有需要在busybox基础上,制作linux,可是却不知道具体怎么做,这里将对基于busybox的linux小系统制作做出详细的步骤说明. 准备环境: 1.一个Redhat完整系统的虚拟机, ...

  5. 怎么导入字体ttf_教程小字体制作精品教程(简化版)丨精致小字体

    公众号分享过缩小字体的详细教程(话说像我这样分享资源还分享详细教程的人快灭绝了吧): 苹方小字体+小字体制作详细教程方法 这个教程虽然复杂一点,不同于之前直接用Scale命令来缩小字体,操作上面需要花 ...

  6. 转wordpress小工具制作前台后台全解析

    wordpress主题制作中对边栏的处理一直是我们比较烦恼的,我们希望边栏的变化更多更复杂,今天我们就来具体讲解下wordpress边栏小工具的制作. 一.让你的主题显示小工具 有些相当简单的主题你会 ...

  7. 基于pygame的射击小游戏制作(一)让飞船动起来

    基于pygame的射击小游戏制作(一)让飞船动起来 一.文件结构 alien_invasion.py 是整个系统的主文件,用来创建游戏中的一系列对象,ai_settings存储设置.screen存储显 ...

  8. 微信小程序傻瓜制作_盘点:微信小程序制作平台有哪些

    如今各行各业商家的流程获取成本不断上升,想要获取更多流量,就得多拓展新的渠道.而微信小程序,由于开启方便.依托于微信这个十亿流量的大平台.流量入口多,已经成了众多知名品牌的选择.利用小程序,商家可以从 ...

  9. wxWidgets:通过组合现有小部件制作新的可重用小部件

    wxWidgets:通过组合现有小部件制作新的可重用小部件 wxWidgets:通过组合现有小部件制作新的可重用小部件 wxWidgets:通过组合现有小部件制作新的可重用小部件 以下是如何通过组合现 ...

最新文章

  1. 盘点:2020 年机器学习 10 大进展
  2. Form_Form与OAF页面互相调用(案例)
  3. java语言的编译器可以用python_jython实现java运行python代码
  4. 链地址处理哈希冲突方法
  5. [bzoj1412][ZJOI2009]狼和羊的故事
  6. mysql创建索引以及进程过程中出现的问题
  7. 一个知乎重度用户眼中的知乎
  8. 拓端tecdat|R语言:逻辑回归ROC曲线对角线分析过程及结果
  9. 初学C语言2--C语言项目的基本框架
  10. 盒子模型补充知识汇总
  11. linux invalid argument_Linux命令很熟悉,你知道它们的英文全称和中文解释吗?
  12. windbg 常用命令
  13. ArrayList集合
  14. iOS10.3正式版发布:iOS10.3新功能有哪些? 韩俊强的博客
  15. 解决报错:Fan in and fan out can not be computed for tensor with fewer than 2 dimensions
  16. java快速入门知识整理:9、java数据类型:布尔型(boolean)
  17. Java7 新特性:MethodHandler,MethodHandles,MethodHandles.Lookup用法详解
  18. 原装RFX2401C集成电路2.4GHZ单芯片射频前端IC无线教学模块
  19. 【机器人基础】机器人学精简笔记-空间描述和变换
  20. C++之spriintf函数(itoa函数)

热门文章

  1. Cannot parse 1989-04-16: Illegal instant due to time zone offset transition (A
  2. 2019校招春招面试问题汇总
  3. 采集文章发布到Discuz论坛指定版块
  4. Android手机截屏生成gif图片
  5. 助推建筑项目高质量建设,智慧工地用数字化赋能
  6. css3 太极动画,纯css实现太极阴阳鱼动画
  7. java:集合(Collection【List(ArrayList Vector LinkedList)、set】、Map【hashMap、treeMap、hashtable、properties】)
  8. PHP Web网页实时显示海康摄像头监控画面
  9. 网站被挂马怎么解决_网站被黑解决办法
  10. 都是工作好几年的网络工程师,你可千万别再这样写年终总结了