音乐播放器设计说明
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
音乐播放器说明书
音乐播放器设计说明
1、设计目的
充分利用EITS2003 多用途EDA 开发实验平台的设计资源,完成一个比较复杂的FPGA 设计方案,增强对FPGA 设计的更深理解,提高设计水平,为今后的更复杂的FPGA 设计实践打下坚实的基础。
2、设计概述
EITS2003 多用途EDA 开发实验平台给我们提供了丰富的设计资源。它的核心器件为Xilinx 公司的Spartan-IIE 系列的FPGA 芯片,且在FPGA 周围提供了丰富的资源:有串口、PS/2 接口、VGA 接口、LED 和七段数码管显示、拨码开关和按钮、AT89S52 单片机、SRAM、I2C、A/D D/A 转换、扬声器、电源、电源晶振等。
这就为我们的设计提供了丰富的选择。考虑到以后实践的需要,且又要达到一定的难度,我们选择了把几种常用接口PS/2、LED 显示结合的一个电路。虽然设计并不是很复杂,但其实践意义是很大的。
3、设计方案说明
3.1 总体方案
我们设计的总体思想是:利用EITS2003上的拨码开关选择不同的歌曲进行播放,并在相应的七段数码管及LED显示正在播放的音阶。
3.2 关键部分说明
3.2.1 音乐电路
音乐电路原理:组成乐曲的每个音符的频率值(音调)及持续时间(音长)是实际乐曲演奏的两个基本数据。因此只要控制输出到扬声器的激励信号的频率和信号的持续时间就可以发出持续的乐曲声。
频率的高低决定了音调的高低。音乐的十二平均率规定:每连个八度音(如简谱中的中音1与高音1)之间的频率相差一倍。在两个八度音之间,又可以分为十二个半音,每两个半音的频率比为12sqr(2)。另外,音名A(简谱中的低音6)的频率为440Hz,音名B到C之间,E到F之间为半音,其余为全音。由此简谱中从低音1到高音1之间的每个音名对应的频率如下表3所示:
3.3 具体实现 3.3.1 顶层模块
TOP
switch1,2,3
reset
l1,2,3,4,5,6,7
dig1,2,3LED
speaker clock
顶层模块的输入输出如上图所示。 输入:
clock 是电路板时钟的输入,50 兆赫兹; reset 用于系统的初始化;
switch1、switch2、switch3是EITS2003的拨码开关输入,产生音乐选择信号。
输出:
speaker 用于输出不同频率的时钟,使得蜂鸣器发出不同声音; LED 为七段数码管,用于显示高中低音音阶;
dig1、dig2、dig3为三段数码管的控制信号,选择数码管的输出; l1、l2、l3、l4、l5、l6、l7为LED 显示,指示现输出音阶高低。 这些输入输出的对应管脚如下图所示:
3.3.2 该工程模块结构
ShowKey
HEX2LED Freqorigin
song1switch Freq_Div top
工程模块层次结构图
3.3.3 程序说明 3.3.3.1 Freq_Div 模块
/*****************************************************************************/ Freq_Div.v
模块名称: Freq_Div()
模块功能: 按输入参数对输入时钟进行分频,输出 Clk_User <= Clk_Sys/Div
输入输出: Clk_Sys 输入,输入时钟,一般为系统时钟,1 位 Div 输入,分频参数输入,26 位
Clk_User 输出,分频后的时钟输出,1 位
/*****************************************************************************/ module Freq_Div(Clk_Sys,Div,Clk_User,Reset);
input Clk_Sys;
input [25:0] Div;
output Clk_User;
input Reset;
reg Clk_Usertemp;
reg[25:0] cout;
assign Clk_User=(Div>=2)?Clk_Usertemp:Clk_Sys; //若Div比2小,输出系统时钟
always @(posedge Clk_Sys or negedge Reset) //等待系统时钟上升沿
if(!Reset)
begin
cout<=26'b0;
Clk_Usertemp<=1'b0;
end
else
begin
if(Div>=26'h000_0002)
begin
if(cout>=Div-1) //输出达到一个周期,重新开始
begin
Clk_Usertemp<=1'b0;
cout<=26'h000_0000;
end
else if(cout>=((Div>>1)-1))
begin
cout<=cout+1;
Clk_Usertemp<=1'b1;
end
else
begin
Clk_Usertemp<=1'b0;
cout<=cout+1;
end
end
end
endmodule
3.3.3.2HEX2LED 模块
/****************************************************************************/ HEX2LED.v
/****************************************************************************/
//***************************************************************************** //HEX-to-seven-segment decoder
// input [3:0] HEX;
// output [6:0] LED;
// reg [6:0] LED;
//
// segment encoding
// 0
// //-
// 5 | | 1
// //- <- 6
// 4 | | 2
// //-
// 3
//***************************************************************************** module HEX2LED(HEX,LED);
//***************************************************************************** // HEX:输入十六进制信号
// LED:输出显示信号
//***************************************************************************** input [3:0] HEX;
output [6:0] LED;
reg [6:0] LED;
always @(HEX)
begin
case (HEX)
4'b0001 : LED <= 7'b0000110; //1
4'b0010 : LED <= 7'b1011011; //2
4'b0011 : LED <= 7'b1001111; //3
4'b0100 : LED <= 7'b1100110; //4
4'b0101 : LED <= 7'b1101101; //5
4'b0110 : LED <= 7'b1111101; //6
4'b0111 : LED <= 7'b0000111; //7
4'b1000 : LED <= 7'b1111111; //8
4'b1001 : LED <= 7'b1101111; //9
4'b1010 : LED <= 7'b1110111; //A
4'b1011 : LED <= 7'b1111100; //b