进阶项目(4)蜂鸣器程序设计讲解

本文介绍了如何使用FPGA设计一个蜂鸣器音乐播放器,包括蜂鸣器的工作原理、无源蜂鸣器的特点,以及如何通过FPGA控制蜂鸣器播放音乐。设计中涉及PLL模块、ROM模块、计数器模块、地址生成模块、解码模块和音乐生成模块,通过这些模块组合实现音乐的播放。
摘要由CSDN通过智能技术生成

写在前面的话

经过前面内容的学习,梦翼师兄相信大家的基础知识水平一定已经很扎实。那么本节,我们就一起来庆祝一下,用播放器奏响一曲《欢乐颂》,奏响我们凯旋的乐章。

什么是蜂鸣器

蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、电子玩具、定时器等电子产品中作为发声器件。蜂鸣器分为有源蜂鸣器和无源蜂鸣器两种,在电路中用字母“H”或“HA”(旧标准用“FM”、“ZZG”、“LB”、“JD”等)表示。那么,怎么区分有源蜂鸣器和无源蜂鸣器呢?有源蜂鸣器内部带震荡源,所以只要一通电就会叫;而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。必须用2K-5K的方波去驱动它,有源蜂鸣器往往比无源的贵,就是因为里面多个震荡电路。无源蜂鸣器的优点是:

1. 便宜;

2. 声音频率可控,可以做出“多来米发索拉西”的效果;

3. 在一些特例中,可以和LED复用一个控制口

有源蜂鸣器的优点是:程序控制方便。

FPGA应用的设计上,很多方案都会用到蜂鸣器,大部分都是使用蜂鸣器来做提示或报警,比如按键按下、开始工作、工作结束或是故障等等。当然,我们也可以让它为我们演奏喜欢的音乐。在设计之前,我们先来了解一下声音是怎么播放出来的。我们在本次设计中,用到的是一个无源蜂鸣器,如下图所示:

由于蜂鸣器的工作电流一般比较大,以至于FPGA的I/O 口是不能很好地直接驱动它的,所以要利用三极管开关特性来引入电源电压信号,我们知道无源蜂鸣器的主要特点是内部不带振荡源,所以如果使用直流信号是无法驱动无源蜂鸣器鸣叫的,因此必须使用方波去驱动它。

现在我们明白了,只要给蜂鸣器发送一定频率的方波,就可以使得蜂鸣器发出声音,然而现在的问题就转化为-我们究竟要给蜂鸣器发送什么频率的方波信号呢?具体的频率可以查表如下:

 

现在我们知道了如何让蜂鸣器发出声音,又知道发送多大频率可以让蜂鸣器响起什么样声音,所以我相信我们已经有能力让蜂鸣器响起我们需要的音乐了。

设计任务

下面我们用FPGA来设计一个蜂鸣器的播放器,梦翼师兄开发板上的晶振是50Mhz的,所以我们需要一个锁相环模块(PLL)来得到低频率的时钟,然后再用这个比较低的频率来分出所需要的频率来驱动蜂鸣器。有了锁相环(PLL后,我们还需要一个空间来保存乐谱,由于乐谱是确定的,不需要更改,所以我们选择一个简单的存储器就可以了,这里我们使用的是 ROM,可以直接通过IP 核来创建。 

既然是播放音乐,那么就需要节拍(一般为 4 拍),因此我们还需要一个节拍控制器, 例如,我们现在需要发出一个低音 1 并维持一秒,那怎么办呢? 我们可以设计一个模块,控制每 0.25s ROM 的地址加一,若要使发出的低音 1 维持 1 钟,我们仅需在 ROM 的四个连续地址中写入低音 1 的对应信息即可

具体的设计架构图如下所示:

 

由上图可知,整个FPGA设计里面一共有6个模块,其中PLL模块,用来将50Mhz的晶振时钟信号分频得到1Mhz的系统时钟ROM模块用来存储想要播放的音乐数据,time_counter模块是一个计数器模块,当计数到0.25秒之后,time_counter输出的time_finsh信号会变一个时钟周期的高电平,发送给 addr_gen模块。当addr_gen接收到这个高电平之后,就会Rom发送一个地址信号ROM输出数据,简单来说,就是在0.25秒之后,把ROM的地址加一,读取下一个数据。 decode解码模块,是把从Rom中读出来的数据解码然后发送到music_gen模块,产生特定的方波频率。

为了方便我们往ROM里保存数据,比如保存的数据是8’hAB,其中A设定只有3个值,分别是1,2,4来表示低音、中音和高音,而B设定有7个值,分别是1,2,3,4,5,6,7,比如现在要产生一个低音1,仅仅需要在ROM里面写8’h11,需要产生一个高音5,则需要在ROM里面写8’h45依次类推。但是实际上,你要产生一个低音1,然后把ROM里面的8’h11发给music_gen模块是不行的,因为在ROM里面的数据是为了方便我们才定义成这样的格式,所以我们这里需要一个decode模块(解码模块)来把ROM的数据还原成music_gen所需要的数据。

time_counter的功能很简单,就不断的计数,当计数到249_999(1Mhz/4Hz=250_000-1,4Hz=0.25S)的时候数据选择器选择18’d0,让count归零,然后又继续累加,直到计数到249_999,不断这样循环。

下面附上一首《欢乐颂ROM数据

 

 

 

端口介绍

顶层端口及其意义如下:

 

端口名

端口说明

clk_50M

系统50MHz时钟输入

rst_n

系统低电平复位

beep_out

蜂鸣器输入

内部连线及其意义如下

 

 

端口名

端口说明

clk_1M

系统驱动时钟

time_finish

0.25s节拍定时标志

addr

Rom读数据地址

rom_data

解码前音符编码数据

music_data

分频后解码预置数

 

 代码解释

 

time_counter 模块

 

/****************************************************          

 *   Engineer      :   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值