vhdl实验报告蜂鸣器Word格式文档下载.docx

上传人:b****4 文档编号:18022074 上传时间:2022-12-12 格式:DOCX 页数:11 大小:37.42KB
下载 相关 举报
vhdl实验报告蜂鸣器Word格式文档下载.docx_第1页
第1页 / 共11页
vhdl实验报告蜂鸣器Word格式文档下载.docx_第2页
第2页 / 共11页
vhdl实验报告蜂鸣器Word格式文档下载.docx_第3页
第3页 / 共11页
vhdl实验报告蜂鸣器Word格式文档下载.docx_第4页
第4页 / 共11页
vhdl实验报告蜂鸣器Word格式文档下载.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

vhdl实验报告蜂鸣器Word格式文档下载.docx

《vhdl实验报告蜂鸣器Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《vhdl实验报告蜂鸣器Word格式文档下载.docx(11页珍藏版)》请在冰豆网上搜索。

vhdl实验报告蜂鸣器Word格式文档下载.docx

1318.5

低音4

349.2

中音4

698.5

高音4

1391.1

低音5

392

中音5

784

高音5

1568

低音6

440

中音6

880

高音6

1760

低音7

493.9

中音7

987.8

高音7

1975.5

表2.1简谱音名与频率的对应关系

产生各音符所需的频率可用一分频器实现,由于各音符对应的频率多为非整数,而分频系数又不能为小数,故必须将计算得到的分频数四舍五入取整。

若分频器时钟频率过低,则由于分频系数过小,四舍五入取整后的误差较大;

若时钟频率过高,虽然误差变小,但分频数将变大。

实际的设计应综合考虑两方面的因素,在尽量减小频率误差的前提下取合适的时钟频率。

实际上,只要各个音符间的相对频率关系不变,演奏出的乐曲听起来都不会走调。

音符的持续时间须根据乐曲的速度及每个音符的节拍数来确定。

因此,要控制音符的音长,就必须知道乐曲的速度和每个音符所对应的节拍数,本例所演奏的乐曲的最短的音符为四分音符,如果将全音符的持续时间设为1s的话,那么一拍所应该持续的时间为0.25秒,则只需要提供一个4HZ的时钟频率即可产生四分音符的时长。

本例设计的音乐电子琴选取40MHZ的系统时钟频率。

在数控分频器模块,首先对时钟频率进行40分频,得到1MHZ的输入频率,然后再次分频得到各音符的频率。

由于数控分频器输出的波形是脉宽极窄的脉冲波,为了更好的驱动蜂鸣器发声,在到达蜂鸣器之前需要均衡占空比,从而生成各音符对应频率的对称方波输出。

这个过程实际上进行了一次二分频,频率变为原来的二分之一即0.5MHZ。

因此,分频系数的计算可以按照下面的方法进行。

以中音1为例,对应的频率值为523.3Hz,它的分频系数应该为:

至于其他音符,同样可由上式求出对应的分频系数,这样利用程序可以很轻松地得到相应的乐声。

分频系数

1911

478

1702

425

1517

379

1431

359

1276

319

1136

284

1014

253

956

851

中音3659.3758中音4698.5716

中音5784638中音6880568

中音7987.8506

表2.2各音名对应的分频系数

至于音长的控制,在自动演奏模块,每个乐曲的音符是按地址存放的,播放乐曲时按4HZ的时钟频率依次读取简谱,每个音符持续时间为0.25秒。

如果乐谱中某个音符为三拍音长,那又该如何控制呢?

其实只要在3个连续地址存放该音符,这时就会发三个0.25秒的音长,即持续了三拍的时间,通过这样一个简单的操作就可以控制音长了。

三、实验步骤

1、设置端口

1)输入端口

CLK:

40MHZ系统时钟输入端口。

2)输出端口

device:

乐曲的声音输出端口,输出的是对应各音符频率的方波信号。

2、设置模块

1)自动演奏模块

自动演奏模块可以自动播放电子琴内置乐曲,按节拍读取内置乐谱。

将键盘输入的音符信号输出。

因此,本模块是向Tone模块提供音符信息。

首先,对40MHz系统时钟进行10M的分频,得到4Hz的信号,这样一秒中就可以按照四拍进行。

然后依照此频率进行地址累计。

2)音频发生器模块

根据自动演奏模块的信号输出,不同的信号被翻译为不同的频率。

3)蜂鸣器驱动模块

根据音频发生器发出音频的不同,蜂鸣器得到的驱动也不同。

首先,对系统时钟进行40分频,再对1mhz的脉冲再次分频,得到所需要的音符频率,然后再进行2分频。

四、实验代码

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entitytoneis

port(

index:

instd_logic_vector(15downto0);

--音符输入信号

tone0:

outintegerrange0to2047--音符的分频系数

);

endtone;

architecturebehavioraloftoneis

begin

search:

process(index)--此进程完成音符到音符的分频系数译码,音符的显示,高低音阶

begin

caseindexis

when"

0000000000000001"

=>

tone0<

=1433;

0000000000000010"

=1277;

0000000000000100"

=1138;

0000000000001000"

=1074;

0000000000010000"

=960;

0000000000100000"

=853;

0000000001000000"

=759;

0000000010000000"

=716;

0000000100000000"

=358;

0000001000000000"

=319;

0000010000000000"

=284;

0000100000000000"

=268;

0001000000000000"

=239;

0010000000000000"

=213;

0100000000000000"

=190;

1000000000000000"

=638;

whenothers=>

=0;

endcase;

endprocess;

endbehavioral;

 

entityspeakeris

clk1:

instd_logic;

--系统时钟12mhz

tone1:

inintegerrange0to2047;

--音符分频系数

spks:

outstd_logic--驱动扬声器的音频信号

endspeaker;

architecturebehavioralofspeakeris

signalpreclk,fullspks:

std_logic;

p1:

process(clk1)--此进程对系统时钟进行16分频

variablecount:

integerrange0to16;

ifclk1'

eventandclk1='

1'

thencount:

=count+1;

ifcount=8then

preclk<

='

;

elsifcount=16then

0'

count:

endif;

endif;

endprocessp1;

p2:

process(preclk,tone1)--对0.75mhz的脉冲再次分频,得到所需要的音符频率

variablecount11:

integerrange0to2047;

ifpreclk'

eventandpreclk='

then

ifcount11<

tone1then

count11:

=count11+1;

fullspks<

else

endprocessp2;

p3:

process(fullspks)--此进程对fullspks进行2分频

variablecount2:

std_logic:

iffullspks'

eventandfullspks='

count2:

=notcount2;

ifcount2='

spks<

endif;

endprocessp3;

entitylaohuis

clk:

--系统时钟;

键盘输入/自动演奏

tone_key_0:

bufferstd_logic_vector(15downto0)--音符信号输出

endlaohu;

architecturebehavioraloflaohuis

signalcount0:

integerrange0to31;

--change

signalclk2:

process(clk)--对12mhz系统时钟进行3m的分频,得到4hz的信号clk2

integerrange0to3000000;

ifclk'

eventandclk='

count:

ifcount=1500000then

clk2<

elsifcount=3000000then

process(clk2)--此进程完成自动演奏部分乐曲的地址累加

ifclk2'

eventandclk2='

ifcount0=29then

count0<

else

=count0+1;

process(count0,tone_key_0)

casecount0is--此case语句:

存储自动演奏部分的乐曲

when0=>

tone_key_0<

=b"

00000001_00000000"

--1

when1=>

00000010_00000000"

--2

when2=>

00000100_00000000"

--3

when3=>

when4=>

when5=>

when6=>

when7=>

when8=>

when9=>

00001000_00000000"

--4

when10=>

00010000_00000000"

--5

when11=>

when12=>

when13=>

when14=>

when15=>

00100000_00000000"

--6

when16=>

when17=>

when18=>

when19=>

when20=>

when21=>

when22=>

when23=>

when24=>

when25=>

when26=>

when27=>

00000000_00100000"

--di6

when28=>

null;

endcase;

entitybeep0is

instd_logic;

device:

outstd_logic

endbeep0;

architecturebehavioralofbeep0is

componentlaohuis

outstd_logic_vector(15downto0)--音符信号输出

endcomponent;

componenttoneis

--音符输入信号

outintegerrange0to2047--音符的分频系数

componentspeakeris

--系统时钟12mhz

outstd_logic--驱动扬声器的音频信号

signalmid:

std_logic_vector(15downto0);

signaltones:

integer;

u0:

laohuportmap(clk,mid);

u1:

toneportmap(mid,tones);

u2:

speakerportmap(clk,tones,device);

五、实验结果及其分析

频率折算中,由于频率计数3不能是小数,采用了四舍五入的方法,所以得到的频率并不是十分精确的,但是不会影响结果。

乐曲按照每秒钟四拍进行,循环地从事先编好的代码中翻译出频率来,所以能听到完整的乐曲。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1