verilog实验1:基于FPGA蜂鸣器演奏乐曲并数码管显示
一、实验任务
利用FPGA进行代码开发,使蜂鸣器演奏出乐曲《生日快乐》,将音调显示在数码管。原理为蜂鸣器为交流源蜂鸣器,在引脚上加一定频率的方波就可以发声,而且发声的频率由所加方波决定。这样我们就可以根据无源蜂鸣器的原理进行发声练习了。
二、代码实现
由于需要蜂鸣器发声且数码管显示音调,所以我们将代码分为两部分。
第一部分用于产生音调的方波。第二部分为数码管显示。
(一)产生音调
(1)PreDiv 预置分频数模块
将48M晶振分频12M,再计算得出各个音调的频率,公式为12M÷音调频率÷2,所得即为预置分频数。程序中只编写了低音和中音的14个音。
- module prediv(
- input [:]Index,
- input clk,
- input Reset_n,
- output reg[:] PreDiv
- );
- always @ (negedge Reset_n or posedge clk)
- if(!Reset_n)
- begin
- PreDiv<='h5997;
- end
- else
- begin
- case(Index)
- 'd1:PreDiv<=16'h5997;
- 'd2:PreDiv<=16'h4FCD;
- 'd3:PreDiv<=16'h471B;
- 'd4:PreDiv<=16'h431E;
- 'd5:PreDiv<=16'h3BCA;
- 'd6:PreDiv<=16'h3544;
- 'd7:PreDiv<=16'h2F74;
- 'd8:PreDiv<=16'h2CCA;
- 'd9:PreDiv<=16'h27E8;
- 'd10:PreDiv<=16'h238D;
- 'd11:PreDiv<=16'h218E;
- 'd12:PreDiv<=16'h1DE5;
- 'd13:PreDiv<=16'h1AA2;
- 'd14:PreDiv<=16'h17BA;
- endcase
- end
- endmodule
(2)Index 索引数模块
为了便于代码书写,需要引用索引数(其实加一个ROM更为方便),即使用“5“为低音”so",如简谱一样,可以更为方便的编写乐曲。毕竟乐曲有很多音符,如果每次都用预置数编写程序,程序书写和查错会非常不方便。当然这也是verilog语言的魅力之处。
- module index(
- input clk,
- input reset_n,
- output reg[:]index
- );
- reg[:]cnt;
- wire clk2m;
- wire clk2000;
- wire clk2;
- defparam clk_rhythm1.divdWIDTH=,clk_rhythm1.divdFACTOR=;//24分频2M
- div clk_rhythm1(
- .reset(reset_n),
- .clkin(clk),
- .clkout(clk2m)
- );
- defparam clk_rhythm2.divdWIDTH=,clk_rhythm2.divdFACTOR=;//1000分频2000hz
- div clk_rhythm2(
- .reset(reset_n),
- .clkin(clk2m),
- .clkout(clk2000)
- );
- defparam clk_rhythm3.divdWIDTH=,clk_rhythm3.divdFACTOR=;//1000分频2hz
- div clk_rhythm3(
- .reset(reset_n),
- .clkin(clk2000),
- .clkout(clk2)
- );
- always @ (negedge reset_n or posedge clk2)
- if(!reset_n)
- begin
- index<='d0;
- cnt<='h0;
- end
- else
- begin
- if(cnt=='d42)
- cnt<='h0;
- else
- cnt<=cnt+'b1;
- case(cnt)
- 'd1:index<=4'd5;
- 'd2:index<=4'd5;
- 'd3:index<=4'd6;
- 'd4:index<=4'd6;
- 'd5:index<=4'd5;
- 'd6:index<=4'd5;
- 'd7:index<=4'd8;
- 'd8:index<=4'd8;
- 'd9:index<=4'd7;
- 'd10:index<=4'd7;
- 'd11:index<=4'd5;
- 'd12:index<=4'd5;
- 'd13:index<=4'd6;
- 'd14:index<=4'd6;
- 'd15:index<=4'd5;
- 'd16:index<=4'd5;
- 'd17:index<=4'd9;
- 'd18:index<=4'd9;
- 'd19:index<=4'd8;
- 'd20:index<=4'd8;
- 'd21:index<=4'd5;
- 'd22:index<=4'd5;
- 'd23:index<=4'd12;
- 'd24:index<=4'd12;
- 'd25:index<=4'd10;
- 'd26:index<=4'd10;
- 'd27:index<=4'd8;
- 'd28:index<=4'd8;
- 'd29:index<=4'd7;
- 'd30:index<=4'd7;
- 'd31:index<=4'd6;
- 'd32:index<=4'd6;
- 'd33:index<=4'd11;
- 'd34:index<=4'd11;
- 'd35:index<=4'd10;
- 'd36:index<=4'd10;
- 'd37:index<=4'd8;
- 'd38:index<=4'd8;
- 'd39:index<=4'd9;
- 'd40:index<=4'd9;
- 'd41:index<=4'd8;
- 'd42:index<=4'd8;
- endcase
- end
- endmodule
(3)节拍
歌曲中不仅有音调还要有快慢,这个快慢即为节拍。所以我们还是分频分出节拍为0.5s一拍。具体代码见上一部分。
(二)数码管显示
数码管显示的原理是利用人眼的视觉暂留0.05s,数码管动态扫描时间小于等于0.05s,人眼看到数码管就是一直在显示,根据这个原理,我们将音调显示在数码管上。音调即为上文提到的索引数,所以我们编写代码的思路就为将索引数输入,进行一些运算,在数码管上显示。道理十分简单。
- module smdisplay(clk,rst,index,dataout,en);
- input clk,rst;
- input [:]index;
- output[:] dataout;
- output[:] en;//COM使能输出
- reg[:] dataout;//各段数据输出
- reg[:] en;
- reg[:] cnt_scan;//扫描频率计数器
- reg[:] dataout_buf;
- always@(posedge clk or negedge rst)
- begin
- if(!rst)
- begin //低电平复位
- cnt_scan<=;
- end
- else
- begin
- cnt_scan<=cnt_scan+;
- end
- end
- always @(cnt_scan)//段码扫描频率
- begin
- case(cnt_scan[:])
- 'b00 :
- en = 'b1110;
- 'b01 :
- en = 'b1101;
- 'b10 :
- en = 'b1011;
- 'b11 :
- en = 'b0111;
- default :
- en = 'b1110;
- endcase
- end
- always@(en or index) //对应COM信号给出各段数据,段码
- begin
- if(index>= && index<=)
- case(en)
- 'b1110:
- dataout_buf<=index;
- 'b1101:
- dataout_buf<=;
- 'b1011:
- dataout_buf<=;
- 'b0111:
- dataout_buf<=;
- default:
- dataout_buf<=;
- endcase
- else if(index >= && index <=)
- case(en)
- 'b1110:
- dataout_buf<=;
- 'b1101:
- dataout_buf<=index - 'd7;
- 'b1011:
- dataout_buf<=;
- 'b0111:
- dataout_buf<=;
- default:
- dataout_buf<=;
- endcase
- else
- case(en)
- 'b1110:
- dataout_buf<=;
- 'b1101:
- dataout_buf<=;
- 'b1011:
- dataout_buf<=index - 'd14;
- 'b0111:
- dataout_buf<=;
- default:
- dataout_buf<=;
- endcase
- end
- always@(dataout_buf)
- begin
- case(dataout_buf) //将要显示的数字译成段码
- 'b0000://0
- dataout='b0000_0011;
- 'b0001://1
- dataout='b1001_1111;
- 'b0010://2
- dataout='b0010_0101;
- 'b0011://3
- dataout='b0000_1101;
- 'b0100://4
- dataout='b1001_1001;
- 'b0101://5
- dataout='b0100_1001;
- 'b0110://6
- dataout='b0100_0001;
- 'b0111://7
- dataout='b0001_1111;
- 'b1000://8
- dataout='b0000_0001;
- 'b1001://9
- dataout='b0000_1001;
- default://这里仅编译了0-9这几个数字
- dataout='b1111_1111;//全灭
- endcase
- end
- endmodule
之后,我们在顶层编写,将各个模块连接起来。输入输出分清楚。再进行管脚的绑定,我们就可以进行程序的烧写了!烧写如我们所料,可以演奏音乐,并且在数码管上显示音调。
三、感悟
这是在一年前大学里学了EDA课程后,再一次拾起。年轻时候由于EDA是选修课程,尽管很感兴趣也很喜欢讲授课程的老师,但是还是没有很重视起来,觉得这些课程像高数大物之类般看看书完成完成课后作业便可以了,可是在每一次完成老师布置的大作业时的吃力,至今想想还是不容小觑的。那时的我不会查资料,不会从网上看别人发的经验帖,更是看代码也十分粗糙,也不会用仿真软件。总结起来就是不知道这些与时俱进的技术怎么学。现在很高兴的是,我又一次的拾起来这些大概还没忘记的知识。由于实习,我又一次接触了FPGA,并且将其作为我的毕设题目。这次,我一定要吸取经验,努力提高自己。如果不知道该努力什么,那么就把自己现在所面临的每一件事情做好。加油。
verilog实验1:基于FPGA蜂鸣器演奏乐曲并数码管显示的更多相关文章
- 基于FPGA的数字秒表(数码管显示模块和按键消抖)实现
本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿FPGA做秒表真是嫌钱多. 感谢 感谢学校和至芯科技,笔者专业最近去北京至芯科技培训交流了一周.老师的经验还是可以的,优化了自己的代 ...
- 基于FPGA的5寸LCD显示屏的显示控制
基于FPGA的5寸LCD显示屏的显示控制 作者:lee神 1,图像处理基础知识 数字图像处理是指将图像信号转换成数字信号并利用计算机对其进行处理的过程.图像处理最早出现于 20 世纪 50 年代,当时 ...
- 详解树莓派Model B+控制蜂鸣器演奏乐曲
步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这里将用GPIO的PWM接口驱动无源蜂鸣器弹奏乐曲,本文基于树莓派Mode B+,其他版本树莓派实现时需参照相关资料进行修改! 1 预备知识 1.1 ...
- FPGA经典:Verilog传奇与基于FPGA的数字图像处理原理及应用
一 简述 最近恶补基础知识,借了<<Verilog传奇>>,<基于FPGA的嵌入式图像处理系统设计>和<<基千FPGA的数字图像处理原理及应用>& ...
- Raspberry Pi开发之旅-控制蜂鸣器演奏乐曲
一.无源蜂鸣器和有源蜂鸣器 步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这次尝试用GPIO的PWM接口驱动无源蜂鸣器弹奏一曲<一闪一闪亮晶晶>. 无源蜂鸣器: 无源内部没有震荡源, ...
- 基于FPGA的VGA显示实验设计
基于FPGA的VGA显示实验设计 成果展示(优酷视频): 视频: 基于FPGA的VGA显示技术(手机控制) http://v.youku.com/v_show/id_XNjk4ODE3ODUy.htm ...
- 基于FPGA的图像显示
基于FPGA的图像显示 作者:lee神 这几天一直在调试FPGA的图像显示系统,今天终于成功,图像不在闪烁,也不再边框缺失. 基于FPGA的图像处理的第一课应该是基于FPGA的图像显示,只有图像正常显 ...
- verilog实验2:基于FPGA的59秒计时器设计
一.实验任务 利用四个数码管显示59秒计时器. 二.代码实现 将开发板的48M晶振分频出1M,然后计数器累加,将计数器结果显示在数码管上.低位逢十进一,第二位逢五进一,依次构成59秒计时器. 部分代码 ...
- 自己动手写CPU(基于FPGA与Verilog)
大三上学期开展了数字系统设计的课程,下学期便要求自己写一个单周期CPU和一个多周期CPU,既然要学,就记录一下学习的过程. CPU--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...
随机推荐
- bzoj:3994:vijos1949: [SDOI2015]约数个数和
Description 设d(x)为x的约数个数,给定N.M,求 Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. O ...
- poj_2195Going Home(最小费用最大流)
poj_2195Going Home(最小费用最大流) 标签: 最小费用最大流 题目链接 题意: 有n*m的矩阵,H表示这个点是一个房子,m表示这个点是一个人,现在每一个人需要走入一个房间,已经知道的 ...
- A + B Problem II(大数加法)
http://acm.hdu.edu.cn/showproblem.php?pid=1002 A + B Problem II Time Limit: 2000/1000 MS (Java/Other ...
- 在64位系统下,指向int型的指针占的内存空间多大?
不废话,请看代码演示如下: 注意使用的操作系统的位数,不同位数的操作系统,结果不一样! 我是用的是64位的操作系统! linux下示例代码如下: #include <stdio.h> in ...
- 基于.netcore 开发的轻量Rpc框架
Rpc原理详解 博客上已经有人解释的很详细了,我就不在解释了.传送门 项目简介 项目是依赖于.net core2.0版本,内部都是依靠IOC来实现的,方便做自定义扩展.底层的通信是采用socket,s ...
- 微信小程序实现滚动加载更多
1.需要用到的组件和api scroll-view(可滚动视图区域) wx.showToast(OBJECT)显示消息提示窗----显示loading小菊花用的 2.需要用到的属性 3.scrol-v ...
- Npm vs Yarn 之备忘大全
有则笑话,如此讲到:"老丈人爱吃核桃,昨天买了二斤陪妻子送去,老丈人年轻时练过武,用手一拍核桃就碎了,笑着对我说:你还用锤子,你看我用手就成.我嘴一抽,来了句:人和动物最大的区别就是人会使用 ...
- Fiddler显示服务器IP的方法
Fiddler默认配置中是看不到服务器IP的,接下来简单介绍下在fiddler上也能够看到请求的服务器IP: 1.Fiddler--->Rules--->Customize Rules , ...
- dedecms中{dede:myad name='about'/} 修改内容
网站首页index.htm中调用这个命令,显示一段文字,但是想要修改内容.所以想知道这个命令指定的文件内容在哪里寻找或者指定内容在哪里修改? 匿名 | 浏览 6036 次 发布于2014-02-19 ...
- Effective Java 第三版——27. 消除非检查警告
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...