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--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...
随机推荐
- hdu_1010_Tempter of the Bone_dfs
题意:给出一个地图,起点和终点,四通路(上下左右),问在一定的时间内可以走出这个地图吗 题解:首先这个题意一定要好好读,很容易读错题,理解成最短路径小于给定时间就可以出去,其实是不可以的,必须要在给定 ...
- POI Sax 事件驱动解析Excel2007文件
Excel2007版本的代码如下,本文主要是用于POI解析大文件Excel容易出现内存溢出的现象而提出解决方案,故此解决了大数据量的Excel文件解析的难度,在此拿出来贡献给大家,谢谢! 里面用到的相 ...
- 使用vue-axios请求geoJson数据报错的问题
最近的项目用到了echarts一个带有散点地图的图表,按照正常jquery写法应该使用ajax请求geojson的数据动态去切换地图,就像下面这样 $.get('Js/map/' + cityData ...
- [国嵌攻略][158][SPI裸机驱动设计]
SPI控制器工作流程 SPI控制器提供2个SPI接口.每个SPI接口有两个通道,分别为TX通道和RX通道.CPU要写数据到FIFO中,先写数据到SPI_TX_DATA寄存器中,这样此寄存器中的内容就会 ...
- [学习OpenCV攻略][002][Ubuntu下OpenCV安装]
配置环境 操作系统 Ubuntu 12.04 OpenCV版本 opencv-1.0.0 学习书籍 <学习OpenCV> Liunx软件安装方法主要有3种: 1.编译安装,也就是通过编译源 ...
- Vs自定义设置
1.固定选项卡独立行显示设置 效果如下 2.语言设置 可以从官网寻找所需版本语言包 https://my.visualstudio.com/downloads 3.代码段设置 可以对现有的进行一些改造 ...
- (一)surging 微服务框架使用系列之surging 的准备工作rabbitmq安装
(1)下载erlang: http://www.erlang.org/download/otp_win64_17.3.exe 并安装 (2)下载RabbitMQ: http://www.rabbitm ...
- JAVA 键盘输入数组,输出数组内容和最大值、最小值
package shuzu; import java.util.Scanner; import java.util.Arrays; public class shuzu { /** * @param ...
- openfire服务器+Spark搭建即时聊天系统 & 阿里云的初步探索
晚上出去和洋仔吃了涮肉,喝了点啤酒,不知不觉就聊到了11点,感觉他工作状态还不错,emmm...都要加油吧.虽然没有当时去山西零下二十多度那么夸张,这几天北京的冬夜还是有点小冷的.好了进入正题: 一. ...
- 注解Responsebody RequestBody RequestMapping
编写代码时候很容易遗漏注解,尤其比较重要的注解,调试很久也找不到原因,在处理页面请求异常时,如果后台正常,就是发现没有把想要的对象传到页面就注意下看注解是否缺失?例如:/** * @Author gj ...