在学习过程中,大多教材给的代码只能循环进行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. Boost:Porthopper服务测试程序
  2. arcgis python教程视频_arcgispython教程
  3. IAR常用快捷键及使用小技巧
  4. 【java】ThreadLocal 内存泄漏 代码演示 实例演示
  5. WF4.0实战系列索引
  6. Windows11安装Vim编辑器配置指南
  7. JAVA CRC16校验码计算
  8. 如何获取Android手机连接当前网络的外网IP
  9. 2018中南大学 计算机考研分数,2018年中南大学考研复试分数线
  10. AcrelCloud-9500电瓶车充电桩收费平台在公共场所中的应用
  11. 灵异问题,使用EasyConnect后,用navicat可以访问数据库,但是用Idea跑项目连接超时怎么办?
  12. 微信小程序把玩(三十)wx.request(object) API
  13. c语言字符类型中int表示什么,int表示什么数据类型
  14. 2018 年全球人工智能与机器人峰会将在深圳举办
  15. Spring的核心是什么?
  16. 百度地图API-实现底图切换
  17. 5 种值得收藏的图像压缩器工具,可不降低质量压缩图像
  18. CGBitmapContextCreate函数
  19. 黑发不知勤学早,白首方悔读书迟。
  20. json文件格式标准

热门文章

  1. 我用easyswoole v2做了一个http服务
  2. [JS]ipv6地址16进制格式转换为二进制表示
  3. 【福利赠书】有人说,测试驱动开发已死?(文末赠书3本)
  4. iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结)...
  5. 16. cpu的型号决定了计算机的基本性能,CPU的型号决定了计算机的基本性能。
  6. TopResumedActivityChangeItem
  7. 如何在ubuntu16.04上安装eclipse
  8. 进制转换——基于STC89C52RC系列单片机
  9. 认识因特网络(小学计算机课件),小学信息技术- 认识因特网 课件.ppt
  10. 【学术相关】清华教授发文劝退读博:​​我见过太多博士生精神崩溃、心态失衡、身体垮掉、一事无成!...