文档库 最新最全的文档下载
当前位置:文档库 › FPGA设计一个乐曲自动演奏控制器

FPGA设计一个乐曲自动演奏控制器

FPGA设计一个乐曲自动演奏控制器
FPGA设计一个乐曲自动演奏控制器

FPGA设计一个乐曲自动演奏控制器

乐曲自动演奏器

一、功能介绍

使用FPGA设计一个乐曲自动演奏控制器,将源程序下载至FPGA 器件中,实现乐曲自动演奏。(本设计的乐曲是《友谊天长地久》的部分音乐)

乐曲演奏的原理是:由于组成乐曲的每个音符的频率值(音调)及其持续时间(音长)是乐曲演奏的2个基本数据,因此需要控制输出到扬声器的激励信号的频率高低和该频率信号持续的时间。频率的高低决定了音调的高低,而乐曲的简谱与各音名的频率之间也有固定的对应关系。所有不同频率的信号都是从同一基准频率分频而得来的,由于音阶频率多为非整数,而分频系数又不能为小数,故必须将计算的到的分频数进行四舍五入取整,基准频率和分频系数应综合考虑加以选择,从而保证音乐不会走调。如在4MHz时钟下,中音1(对应的频率值为523.3Hz)的分频系数应该为:4000000/(2*523.3)=0xd3821,这样只需对系统时钟进行3821次分频即可得到所要的中音1。至于其他音符,同样可求出对应的分频系数,这样利用程序可以很轻松地得到对应的乐声。此外,在程序中设置了一个状态机,每250ms改变一个状态(即一个节拍),组成乐曲

的每个音符的频率值(音调)相对应于状态机的每一个状态。只要让状态机的状态按顺序转换,就可以自动播放音乐了。《友谊天长地久》乐谱见下表(注:N一拍;N两拍;N﹒四拍;N﹒八拍;N为乐谱。由于芯片存储容量太小,源程序只加入乐谱的一部分音符)

《友谊天长地久》乐谱

0 5. | 1. 1 1 3 | 2. 1 2 3 | 1. 1 3 5 | 6. 6 | 5. 3 3

1 | 2. 1

2

3 | 1. 6. 6 5

.. | 1. 6 | 5. 3 3 1 | 2. 1 2 6

| 5 . 3 3 5 | 6. 1 | 5. 3 3 1 | 2. 1 2 3 | 1. 6. 6 5

..| 1. 0 ?

简谱中的音名与频率的关系

二、硬件设计(电路图、原器件清单)

实物元件清单:

印刷电路板一个;

电阻(10KΩ的10个,200Ω的8个,1KΩ的14个,50Ω的1个);三极管3个;

发光二极管(红黄绿各三个);

蜂鸣器1个;

8段显示器2个;

按键4个;

4M晶振1个;

电容(104的6个,10μ的1个);

电源线1个;

芯片底座1个;

电路图:

功率放大显示部分:

核心控制部分:

三、软件设计(流程图、源程序)

流程图

一个完整的EDA设计流程既是自顶向下设计方法的具体实施途径,也是EDA工具软件本身的组成结构。其大致的设计流程包括:设计输入、综合、适配、时序仿真和功能仿真、编程下载、硬件测试的步骤。对于目前流行的EDA工具软件,图1-1的设计流程具有一般性

[3]。

图1-1 应用FPGA/CPLD的EDA开发设计流程框图

各部分源程序及说明

module song(clk,beep); //模块名称song

//I/O口说明

input clk; //系统时钟4MHz

output beep; //蜂鸣器输出端

//内部寄存器

reg beep_r; //寄存器

reg[3:0] state; //乐谱状态机

reg[15:0]count,count_end;

reg[17:0]count1;

//参数--分频系数

parameter L_5=16'd5102, //低音5

L_6=16'd4545, //低音6

M_1=16'd3821, //中音1

M_2=16'd3405, //中音2

M_3=16'd3033, //中音3

M_5=16'd2551, //中音5

M_6=16'd2273, //中音6

H_1=16 'h1913; //高音6

parameter TIME=1000000; //控制每个音的长短(250ms)assign beep= beep_r; //输出音乐

//上升沿脉冲计数

always@(posedge clk)

begin

count<=count+1'b1; //计数器加1

if(count==count_end)

begin

count<=16'h0; //计数器取0

beep_r<=! beep_r; //输出取反end

end

//上升沿脉冲计数

always@(posedge clk)

begin

if(count1

count1= count1+1'b1;

else

begin

count1=18'd0;

if(state==4'd15)

state= 4'd0;

else

state= state+1'b1;

case(state)

4'd0, 4'd1: count_end=L_5;

4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8 : count_end=M_1;

4'd9, 4'd10: count_end=M_3;

4'd11, 4'd12, 4'd13, 4'd14: count_end=M_2;

4'd15:

count_end=M_1;

default:count_end=16'hffff;

endcase

end

end

Endmodule

引脚锁定方法

四、设计总结

经过我们一组人的共同努力,我们的课程设计完成。在此期间,我们收获颇丰。

首先这是既制作收音机后的又一次焊接印刷电路板的机会,利于提高我们的对器件的辨别、理解能力,还有自己的动手能力。焊好电路板后,我觉得挺麻烦的就是程序的调试。刚开始的调试是在实验室的试验箱上,一切运行正常,但转到我们需要用的芯片上就不能出现我们想要的结果。后来又查资料,了解到芯片的时钟的频率不同,然

后我们就开始转换频率再计算,同时把原来的程序根据要求的频率进行修改,但还是不能显示出流畅的音乐。最后,当我们想放弃这个设计换其他程序设计的时候,我们想起可能是蜂鸣器本身的问题。然后,我们找到以前制作收音机的喇叭,接上后效果还是挺明显的,听到音乐的那一刻确实挺有成功感。

其次,也是对EDA这门课的深入理解与应用。如果说刚开始我还不知道EDA是干嘛的,但现在我可以说写一下简单的程序,看懂一些复杂的程序,然后就是提高了对QuartusⅡ操作能力。

当然,通过这次课程设计,还是发现自己的很多不足。由于当初EDA课程学得不是太好,导致刚开始操作时经常会遇到或大或小的问题,而且这次做的设计我觉得是老师要求里的比较简单的一个,还花费了这么长时间,也说明自己的能力不是太好。事实证明:要想真正掌握这门课还需要再花费一些精力。

相关文档