其他分享
首页 > 其他分享> > 基于fpga的电子琴

基于fpga的电子琴

作者:互联网

基于fpga的电子琴

1.芯片介绍

主流产品:ALTERA公司 、FLEX公司

产品类型:CPLD:EPROM类型,掉电后程序不丢失。

FPGA:SRAM类型,掉电后程序丢失,必须重新编程。

工作电压:5V/3.3V/2.5V/1.8V/1.5V

目前主要产品

MAX7000S/AE,MAX3000A系列、FLEX10KE/ACEX1K系列

APEX20K/20KE系列、APEXII系列、Stratix系列

Cyclone(飓风) 系列、Excalibur系列

1.3 Cyclone(飓风)系列介绍

Altera最新一代SRAM工艺中等规模FPGA:

与Stratix结构类似,是一种低成本FPGA系列:

是目前主流产品,其配置芯片业改用新的产品

可支持多种扩展模块

摄像头模块

VGA模块

2.4寸彩屏

3.2寸彩屏

7寸高清大屏

以太网模块

网口模块

USB模块

高速AD DA

飓风系列

型号(1.5V)逻辑单元锁相环M14K RAM
EP1C32910113
EP1C440002
EP1C65980220
EP1C1212060252
EP1C2020060364

备注:每块RAM为4Kbit,可以另加1位奇偶校验位

Cyclone的下一代产品,低成本FPGA

特性EP2C5EP2C8EP2C20EP2C35EP2C50EP2C70
逻辑单元(LE)4608825618752332165052868416
M14K RAM块263652105129250
RAM总量119808165888239616483840594432115200
嵌入式18*18乘法器1318263586150
锁相环224444
最大可用I/O管脚142182315475450622

第二章 模块介绍

2.1设计分析

根据设计要求,由于乐曲自动演奏机和硬件电子琴的设计已经存在,我们对已有的设计进行修改,形成两个不同功能的模块,然后采用元件例化,拼接两个模块,同时附加一个选择功能模块,以实现乐曲自动演机和硬件电子琴两个功能。

2.2硬件电子琴分析

对于硬件电子琴,参考了实验时使用的程序,已经达到的要求有:

(1)按下key1~key7 分别表示中音的DO、 RE 、 ME、 FA、 SOL、 LA、 S;

(2)按下相应的键有对应LED灯指示。

2.3 乐曲自动演奏机分析

对于乐曲自动演奏机,参考了实验时使用的程序,已经达到的要求有:

(1)可以在电路上能自动演奏乐曲,在这里我们采用的是贝多芬的《欢乐颂》

(2)有相应的LED灯指示高低音。

而对于其他要求:

(1)晶振为12 MHz.

(2)采用CPLD 器件为ALTERA 的EPM7064SL-44。

我们在实验箱验证时,先按照实验箱芯片和晶振进行就修改,在实验箱上确认实验相应功能之后,我们在对应模块的频率数值进行修改,并在对管脚重新锁定即可

2.4整体设计分析

整体设计要求:用key8实现两个功能切换。添加一个选择器,以实现两个功能切换。当key8键没有按下时,电路实现硬件电子琴功能,当key8键按下之后,电路实现乐曲自动演奏机。由于不存在现成可以借鉴的,于是,课程设计任务重心就放在了选择器模块的编写以及整体电路的合成上。

顶层模块输入输出:
在这里插入图片描述

图2-1 顶层文件图形

管脚说明:输入:时钟信号——clk ,按键——[6:0]key ,功能切换键——key7

输出:LED灯——[6:0]led ,蜂鸣器——beep;

Key0: DO key1: RE key2: ME key3:FA key4: SOL

key5: LA key6: SI key7:功能切换键

2.5 设计流程

修改硬件电子琴模块

修改乐曲自动演奏模块

编写选择器

设计顶层文件

综合编译、试验箱测试

试验箱测试

图2-2 设计流程图

第三章 功能划分与模块划分

3.1自动演奏模块

自动演奏模块功能:在按下key7键后,实现可以自动播放乐曲的功能。

3.2 自动演奏设计方案

(1)根据乐曲自动演奏的基本原理设计出适合EDA多功能试验箱的源程序,通过分频模块得到12MHZ的晶振;源程序编写完成,编译调试后,在实验箱上验证其功能;

(2)验证模块是否能完成实践要求的所有功能;然后去掉分频模块,将功能模块做适当的修改,编译调试成功后,将其下载到CPLD实验板上。

方案设计步骤:

(1)在Quartus Ⅱ中建立一个工程项目文件song.qpf,并在该项目下新建Verilog
HDL源程序文件song.v输入程序代码并保存。完整的Verilog HDL程序参考程序清单。

(2)然后在该工程选择目标器件并对相应的引脚进行锁定,在这里所选择器件为Alter公司的EPM7064SL-44芯片。

(3)对该工程文件进行全程编译处理,若在编译中发现错误,则找出错误并更正,直到编译成功。

(4)最后拿出下载电缆,将此电缆的两端分别接到PC机的打印机并口和核心板上的JTAG
接口上,打开电源执行下载命令,把程序下载到CPLD器件中。此时可以得到《欢乐颂》乐曲的演奏以及LED灯的明灭指示其高低音。

3.3硬件电子琴模块

硬件电子琴模块功能:在按下功能切换键key7后,可以实现电子琴功能,即按下key1
到key7的过程中发出相应的高低音。

3.3.1硬件电子琴设计方案

(1)根据硬件电子琴演奏的基本原理设计出适合EDA多功能试验箱的源程序,通过分频模块得到12MHZ的晶振;源程序编写完成,编译调试后,在实验箱上验证其功能;

(2)验证模块是否能完成实践要求的所有功能;然后去掉分频模块,将功能模块做适当的修改后,编译调试成功后,将其下载到CPLD实验板上。

3.3.2设计步骤

(1)在Quarters II中建立一个工程项目文件beep1.qpf。并在该项目下新建Verilog
HDL源程序文件beep1.v,输入程序代码并保存,进行综合编译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。

(2)选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。

(3)对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。

(4)将产生的beep1.sof输出对FPGA进行配置。按下按键KEY1~KEY8就可以开始使用电子琴来演奏音乐了。

第四章 课程设计原理

4.1硬件电子琴设计原理

乐曲演奏的原理是:由于组成乐曲的每个音符的频率值(音调)及其持续时间(音长)是乐曲演奏的2个基本数据,因此需要控制输出到扬声器的激励信号的频率高低和该频率信号持续的时间。频率的高低决定了音调的高低,而乐曲的简谱与各音名的频率对应关系在后面将给出。所有不同频率的信号都是从一基准频率分频而得来的,由于音阶频率多为非整数,而分频系数有不能为小数,故必须将计算得到的分频数进行向下取整,基准频率和分频系数应综合考虑加以选择,从而保证音乐不会走调。如在48MHz
时钟下,中音1(对应的频率值是523.3Hz)的分频系数应该为:48000000/(2*523.3)=45863,这样只需对系统时钟进行45863次分频即可得到所要的中音M1(分频系数计算公式为D=F/2K,由于F/2K之后,会使分频系数D变小,所以功能模块中语句:beep_r<=!beep_r,使得输出取反,K=F/2count_end,消除了前面除以2K的影响)

4.2乐曲自动演奏设计原理

硬件电路和自动演奏的原理同硬件电子琴实验原理类似。至于其他音符,同样可由一式求出对应的分频系数。在程序中设置一个状态机,每250ms改变一个状态(即一个节拍),组成乐曲的每个音符的频率值(音调)相对应于状态机的每一个状态。只要让状态机的状态按顺序转换,就可以自动演奏播放音乐了。

《欢乐颂》乐曲的简谱如图所示:
在这里插入图片描述

图4-1《欢乐颂》简谱图

4.3各模块的实现方法

4.3.1选择器模块实现方法

我们可以对输出进行控制。即让两个模块都工作,但是输出的部分添加选择器,有选择输出信号。当KEY8没有按下时,硬件电子琴的模块输出接到蜂鸣器和LED灯;当KEY8按下时,乐曲自动演奏模块输出接到蜂鸣器和LED灯。从输出进行控制,通过将蜂鸣和LED灯的输入和两个模块的输出有选择的匹配进行切换。通过编译下载到实验箱验证可以实现功能,而且在两种状态的切换时,不会出现无法控制的状况。

4.3.2自动演奏模块实现方法

通过参照实验课本,我们根据相关实验对试验程序进行了简单修改,得到了本次自动演奏模块的歌曲《欢乐颂》,实现其自动演奏功能。

对于自动演奏模块而言,要实现其功能,只需要在顶层模块中添加触发自动演奏模块的触发点,在本程序中,即按下key8按键,屏蔽掉硬件电子琴的时钟信号,而使自动演奏模块的电子时钟信号作为使能信号。

在自动演奏模块中,首先计算出各个音符所对应的参数,对参数进行定义和设计。通过对晶振的控制实现每个音响应时间的长短并且可以修改相关参数实现音长的改变。演奏过程中,设置循环体,即每次演奏结束,可以再从头开始演奏,从而实现自动演奏的自动功能。程序中可以设置每次循环时间,也可以设置循环中断。每个音符都需要驱动蜂鸣器实现其功能。

最后,自动演奏模块中,需要有LED灯的指示,对于这样的要求,我们在程序最后添加了assign赋值语句。实现了每个音符响时对应的LED灯点亮。对于在实验中没有出现的音符所对应的LED灯则设置为高阻态,从而屏蔽LED灯点亮。

在程序中,通过控制TIME从而得到每个音阶所响应的时间,不同晶振所对应的的时间为1s,对应的时间可以控制振荡次数实现控制时间的长短。

if(state == 8’d125) state =
8’d0;语句实现的是自动演奏循环和实现歌曲演奏长短。通过系应该参数从而使歌曲唱到想要唱到的部分。

4.3.3硬件电子琴模块实现方法

在原理部分我们已经知道了硬件电子琴和自动演奏乐曲的原理是相同的,因此在知道了如何实现乐曲演奏模块的方法后,对于硬件电子琴只需要实现同样的方法,就可以实现其模块功能,只不过在硬件电子琴模块中,需要的是利用按键实现其功能。对于每一个按键,在程序中设置各按键所对应的参数即可实现硬件电子琴的功能。

硬件电子琴的功能实现主要靠蜂鸣器和系数得到实现。在试验程序的基础上进行修改系数而得到。控制程序的循环体部分实现了计数和完成清零的操作。通过assign赋值语句实现LED灯的操作,在这里,我们添加了数码管的功能,从而实现了再按下按键的同时,实现数码管显示相对应的音阶大小。

第五章 实验箱设计

5.1硬件电子琴模块程序

在这里插入图片描述

图5-1 硬件电子琴模块图

module beep1(clk,key,beep,led); //模块名称beep

input clk; //系统时钟48MHz

input[6:0]key; //按键输入

output beep; //蜂鸣器输出端

output[6:0]led; //LED输出

reg beep_r; //寄存器

reg[15:0]count,count_end;

reg[6:0]key_r;

reg [13:0]a; //消抖寄存器

always@(posedge clk)

begin

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

if((count == count_end)&(!(count_end == 16’hffff)))

begin

count <= 16’h0; //计数器清零

beep_r <= !beep_r; //取反输出信号

end

end

always @(key)

begin

a=2000; //消抖等待时间

key_r = key; //取键值

case(key_r)

7’b1111110:begin

while(a>0)

begin

a=a-1; end

count_end = 16’hb327;

while(a>0)

begin

a=a-1;

end

end

7’b1111101:begin while(a>0)begin a=a-1 ;end count_end =
16’h9fa0;while(a>0)begin a=a-1; end end //中音2的分频系数值

7’b1111011:begin while(a>0)begin a=a-1 ;end count_end =
16’h8e32;while(a>0)begin a=a-1; end end //中音3的分频系数值

7’b1110111:begin while(a>0)begin a=a-1 ;end
count_end16’h8637;while(a>0)begin a=a-1; end end//中音4的分频系数值

7’b1101111:begin while(a>0)begin a=a-1 ;end count_end =
16’h7794;while(a>0)begin a=a-1; end end //中音5的分频系数值

7’b1011111:begin while(a>0)begin a=a-1 ;end count_end =
16’h6a88;while(a>0)begin a=a-1; end end //中音6的分频系数值

7’b0111111:begin while(a>0)begin a=a-1 ;end count_end =
16’h5ee8;while(a>0)begin a=a-1; end end //中音7的分频系数值

default: begin while(a>0)begin a=a-1 ;end count_end = 16’hffff;while(a>0)begin
a=a-1; end end

endcase

end

assign beep =beep_r; //输出音乐

assign led =key_r; //输出按键状态

endmodule

5.2乐曲自动演奏机程序

在这里插入图片描述

图5-2 乐曲自动演奏模块图

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

input clk; //系统时钟48Mhz

output beep; //蜂鸣器输出端

output[7:0] led;

reg beep_r; //寄存器

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

reg[15:0]count,count_end;

reg[23:0]count1;

//乐谱参数:D=F/2K (D:参数,F:时钟频率,K:音高频率)

//以下是12MHZ晶振状态下的各音高对应的参数

/*parameter L_5 = 16’h3bca, //低音5

M_1 = 16’h2cc9, //中音1

M_2 = 16’h27f8, //中音2

M_3 = 16’h238c, //中音3

M_4 = 16’h218d, //中音4

M_5 = 16’h1de5, //中音5

M_6 = 16’h1aa2; //中音6

parameter TIME = 3000000; //控制每一个音的长短(250ms)*/

//乐谱参数:D=F/2K (D:参数,F:时钟频率,K:音高频率)

parameter L_5 = 16’d61224, //低音5

M_1 = 16’d45863, //中音1

M_2 = 16’d40864, //中音2

M_3 = 16’d36402, //中音3

M_4 = 16’d34359, //中音4

M_5 = 16’d30612; //中音5

parameter TIME = 12000000; //控制每一个音的长短(250ms)

assign beep = beep_r; //输出音乐 ,蜂鸣器

always@(posedge clk)

begin

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

if(count == count_end)

begin

count <= 16’h0; //计数器清零

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

end

end

always @(posedge clk)

begin

if(count1 < TIME) //一个节拍250mS

count1 = count1 + 1’b1;

else

begin

count1 = 24’d0;

if(state == 8’d125) //控制歌曲循环播放时间

state = 8’d0; //循环从头开始

else

state = state + 1’b1; //循环结构体

begin

case(state)

8’d0,8’d1: count_end = M_3;//中音"3",持续2个节拍

8’d2,8’d3: count_end = M_3;//中音"3",持续2个节拍

8’d4,8’d5: count_end = M_4;//中音"4",持续2个节拍

8’d6,8’d7: count_end = M_5;

8’d8,8’d9: count_end = M_5;

8’d10,8’d11: count_end = M_4;

8’d12,8’d13: count_end = M_3;

8’d14,8’d15: count_end = M_2;

8’d16,8’d17: count_end = M_1;

8’d18,8’d19: count_end = M_1;

8’d20,8’d21: count_end = M_2;

8’d22,8’d23: count_end = M_3;

8’d24,8’d25,8’d26: count_end = M_3;

8’d27: count_end = M_2;

8’d28,8’d29,8’d30,8’d31: count_end = M_2;

8’d32,8’d33: count_end = M_3;

8’d34,8’d35: count_end = M_3;

8’d36,8’d37: count_end = M_4;

8’d38,8’d39: count_end = M_5;

8’d40,8’d41: count_end = M_5;

8’d42,8’d43: count_end = M_4;

8’d44,8’d45: count_end = M_3;

8’d46,8’d47: count_end = M_2;

8’d48,8’d49: count_end = M_1;

8’d50,8’d51: count_end = M_1;

8’d52,8’d53: count_end = M_2;

8’d54,8’d55: count_end = M_3;

8’d56,8’d57,8’d58: count_end = M_2;

8’d59: count_end = M_1;

8’d60,8’d61,8’d62,8’d63: count_end = M_1;

8’d64,8’d65: count_end = M_2;

8’d66,8’d67: count_end = M_2;

8’d68,8’d69: count_end = M_3;

8’d70,8’d71: count_end = M_1;

8’d72,8’d73: count_end = M_2;

8’d74: count_end = M_3;

8’d75: count_end = M_4;

8’d76,8’d77: count_end = M_3;

8’d78,8’d79: count_end = M_1;

8’d80,8’d81: count_end = M_2;

8’d82: count_end = M_3;

8’d83: count_end = M_4;

8’d84,8’d85: count_end = M_3;

8’d86,8’d87: count_end = M_2;

8’d88,8’d89: count_end = M_1;

8’d90,8’d91: count_end = M_2;

//8’d92,8’d93: count_end = L_5;

8’d92,8’d93,8’d94,8’d95: count_end = L_5;

//8’d94,8’d95: count_end = M_3;

8’d96,8’d97: count_end = M_3;

8’d98,8’d99: count_end = M_3;

8’d100,8’d101: count_end = M_4;

8’d102,8’d103: count_end = M_5;

8’d104,8’d105: count_end = M_5;

8’d106,8’d107: count_end = M_4;

8’d108: count_end = M_3;

8’d109: count_end = M_2;

8’d110,8’d111: count_end = M_1;

8’d112,8’d113: count_end = M_1;

8’d114,8’d115: count_end = M_2;

8’d116,8’d117: count_end = M_3;

8’d118,8’d119,8’d120: count_end = M_2;

8’d121: count_end = M_1;

8’d122,8’d123,8’d124,8’d125: count_end = M_1;

default:count_end = 16’hffff;

endcase

end

end

end

assign led[0]=(count_end == M_1)?0:1; //控制LED灯的语言

assign led[1]=(count_end == M_2)?0:1;

assign led[2]=(count_end == M_3)?0:1;

assign led[3]=(count_end == M_4)?0:1;

assign led[4]=(count_end == M_5)?0:1;

assign led[5]=(count_end == L_5)?0:1;

assign led[6]=1;

assign led[7]=1;

endmodule

5.3 选择模块程序

在这里插入图片描述

图5-3选择模块图

module select(key,beep1,beep2,led1,led2,beep,led);

input key,beep1,beep2;

input [6:0]led1;

input [6:0]led2;

output beep;

output [6:0]led;

reg key_r;

always @(negedge key)

begin

key_r = ~key_r; //将琴键开关转换为乒乓开关

end

assign beep=(key_r)?beep2:beep1;

assign led=(key_r)?led2:led1;

endmodule

5.4顶层文件程序

在这里插入图片描述

图5-4顶层文件图

module dzq(key,key7,beep,led,clk);

input key7;

input [6:0]key;

input clk;

output [6:0]led;

output beep;

reg dout1;

reg dout2;

reg dout3;

reg led;

reg key_r;

wire a,b,key_l;

wire [6:0]c;

wire [6:0]d;

assign key_l = (dout1 | dout2 | dout3); //按键消抖输出

always @(posedge clk)

begin

dout1 <= key7;

dout2 <= dout1;

dout3 <= dout2;

end

song (.clk(clk),.beep(b),.led©);

beep1 (.clk(clk),.key(key),.beep(a),.led(d));

select
(.key(key_l),.beep1(a),.beep2(b),.beep(beep),.led(led),.led1(d),.led2©);

endmodule

第六章 实验图形文件

6.1管脚锁定图

引脚锁定:选择Assignments-pin planer

在这里插入图片描述

图6-1管脚锁定图

RTL图:选择Tools—netlist viewers—RTL viewers

在这里插入图片描述

图6-2 RTL图

6.2DXP原理图及封装

DXP原理图的设计:

  1. 执行“文件”—“创建”—“项目”—“PCB项目”命令

  2. 在projects面板上新建一个项目文件,默认名为PCB_Projects.PrjPCB.

  3. 执行“文件”—“保存项目”命令

  4. 利用libiaries元件库进行原理图绘制[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gkfixX2B-1619190062459)(media/1ed97cb6d418261290cf9e340dc7bbc0.png)]
    在这里插入图片描述

图6-3 dxp原理图

DXP封装设计:

  1. 执行“文件”—“创建”—“PCB文件”命令,新建PCB设计文件并保存

  2. 设置工作层:选择机械层设置物理边界,在禁止布线层设置电气边界。

  3. 加载网络表:执行“设计”—Import Changes From
    DESIGN.PRJPCB命令,单击“使变化生效”—“执行变化”

  4. 元件自动布局:执行“工具”—“放置元件”—“自动布局”命令

  5. 元件自动布线:执行“自动布线”—“设定”—“全部对象”命令,选择默认设置,确认布线即可

在这里插入图片描述

图6-4封装图

6.3任务完成情况说明

编号功能完成状况
1按下KEY1—KEY7 分别表示中音的DO、 RE 、 ME、 FA、 SOL、 LA、 SI;达成
2对于电子琴,按下相应的键有对应LED灯指示达成
3可以在电路上能自动演奏乐曲。在这里我们采用的是贝多芬的《欢乐颂》,且有相应的LED灯指示高低音;达成
4能实现电子琴和乐曲自动演奏功能的切换达成

表6-5 任务完成情况表:

6.4硬件连接图

在这里插入图片描述

在这里插入图片描述

总结

本次EDA课程设计进一步加深了我们对实验课的认识和对EDA的了解,对于Verilog
HDL语言的运用更加的熟练。同时对于课程设计过程中要进行的调试和编写程序有了一定的认识。

电子琴使用按键的冲突,不得不消除原有模块的高音阶部分,而将其改造出现在的模块和形式,对于硬件电子琴的改造,看似是对原功能块的简单的改进,而实际上是需要重新构造电路的,因为在演奏的过程中会有LED灯的使用冲突,如何调试和调用,才是本课程设计的重点,因为顶层文件的需要,我们需要对各自的程序进行调整和修改。目的是为了能够在最后的开发平台上得到我们想要的结果。

在这次的课程设计过程中,我们采取的分工合作的方式来进行课程设计是一件很好的事情。大家各有侧重点但是同时都为课程设计做出应该做的努力,分工协作有时候不仅有利用于课程设计的快速进行,而且也有利于个人和小组的交流和促进,在分工的时候,每个人都各尽所长,实现了又快又好的完成课程任务的目标。最后,特别感谢本次课程设计给予我们指导的老师,在老师的知道和启发下,我们才能正确的完成课程设计。

参考文献

1潘松,黄继业,陈龙.2009.EDA技术与Verilog HDL.北京:清华大学出版社

2王金明,杨吉斌.2002.数字系统设计与Verilog HDL.北京:电子工业出版社

3 郭照男 孙胜麟,2012.4电子技术与EDA技术实验及仿真,中南大学出版社

4王晓莉,2016,电子线路CAD,北京邮电大学出版社,

附录:项目实物图

总结

本次EDA课程设计进一步加深了我们对实验课的认识和对EDA的了解,对于Verilog
HDL语言的运用更加的熟练。同时对于课程设计过程中要进行的调试和编写程序有了一定的认识。

电子琴使用按键的冲突,不得不消除原有模块的高音阶部分,而将其改造出现在的模块和形式,对于硬件电子琴的改造,看似是对原功能块的简单的改进,而实际上是需要重新构造电路的,因为在演奏的过程中会有LED灯的使用冲突,如何调试和调用,才是本课程设计的重点,因为顶层文件的需要,我们需要对各自的程序进行调整和修改。目的是为了能够在最后的开发平台上得到我们想要的结果。

在这次的课程设计过程中,我们采取的分工合作的方式来进行课程设计是一件很好的事情。大家各有侧重点但是同时都为课程设计做出应该做的努力,分工协作有时候不仅有利用于课程设计的快速进行,而且也有利于个人和小组的交流和促进,在分工的时候,每个人都各尽所长,实现了又快又好的完成课程任务的目标。最后,特别感谢本次课程设计给予我们指导的老师,在老师的知道和启发下,我们才能正确的完成课程设计。

参考文献

1潘松,黄继业,陈龙.2009.EDA技术与Verilog HDL.北京:清华大学出版社

2王金明,杨吉斌.2002.数字系统设计与Verilog HDL.北京:电子工业出版社

3 郭照男 孙胜麟,2012.4电子技术与EDA技术实验及仿真,中南大学出版社

4王晓莉,2016,电子线路CAD,北京邮电大学出版社,

附录:项目实物图

在这里插入图片描述

标签:count,基于,end,fpga,begin,演奏,模块,电子琴
来源: https://blog.csdn.net/weixin_44830487/article/details/116074997