新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 基于 STEP-MAX10M08核心板的简易电子琴设计

基于 STEP-MAX10M08核心板的简易电子琴设计

作者:时间:2023-11-27来源:小脚丫STEP开源社区收藏

实验任务

  • 任务:基于 核心板 和 底板 完成简易设计并观察调试结果
  • 要求:按动矩阵键盘,驱动底板无源蜂鸣器发出产生不同音调,弹奏一首《小星星》。
  • 解析:通过编程驱动矩阵键盘电路,获取矩阵键盘键入的信息,然后通过编码将键盘输出的信息译码成对应的音节数据,最后通过PWM发生模块驱动底板上的无源蜂鸣器发出声音。

实验目的

在基础数字电路实验部分我们已经掌握了设计PWM信号发生器的原理及方法,上节实验中又学习了矩阵键盘的驱动原理及方法,本实验主要学习无源蜂鸣器的驱动原理,同时熟悉PWM发生模块及矩阵键盘驱动模块的实例化应用。

本文引用地址:http://www.eepw.com.cn/article/202311/453309.htm
  • 熟悉PWM信号发生驱动模块和矩阵键盘驱动模块的应用
  • 了解无源蜂鸣器的驱动原理及方法
  • 完成简易设计实现

设计框图

根据前面的实验解析我们可以得知,该设计总体可以拆分成两个功能模块实现,

  • ArrayKeyBoard:通过驱动矩阵键盘工作获取键盘的操作信息数据。 * Beeper:根据键盘按键信息驱动无源蜂鸣器发出不同的音节。 顶层模块ElectricPiano通过实例化两个子模块并将对应的信号连接,最终实现简易的总体设计。我们知道无源蜂鸣器是通过交流信号驱动的,可以通过输出不同频率的PWM脉冲信号控制蜂鸣器产生不同的音节输出,所以上面Beeper模块又可以拆分成两个功能模块实现其功能
  • tone:通过编码方式将键盘的操作信息译码成对应的PWM周期信息。
  • PWM:根据PWM周期信息产生对应的PWM脉冲信号。

image.png

image.png

实验原理

蜂鸣器介绍

蜂鸣器的分类: 按其结构主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型:

  • 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。
  • 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。多谐振荡器由晶体管或集成电路构成,当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。

按是否带有信号源分为有源蜂鸣器和无源蜂鸣器两种类型:

  • 有源蜂鸣器只需要在其供电端加上额定直流电压,其内部的震荡器就可以产生固定频率的信号,驱动蜂鸣器发出声音。
  • 无源蜂鸣器可以理解成与喇叭一样,需要在其供电端上加上高低不断变化的电信号才可以驱动发出声音。

我们底板上集成的蜂鸣器为无源电磁式蜂鸣器,接下来和大家一起学习无源蜂鸣器的驱动

蜂鸣器驱动电路

无源蜂鸣器没有集成振荡器,需要外部提供震荡激励,当震荡频率不同时发出不同的音调,对于数字系统来说,方波信号产生方便可靠,成为外部震荡激励的首选,方波信号输入谐振装置转换为声音信号输出,电磁式蜂鸣器需要的驱动电流较高,一般单片机和FPGA管脚驱动能力有限不能直接驱动,常用三极管增加驱动能力,另外电磁式蜂鸣器内部含有感应线圈,在电路通断瞬间会产生感应电势,为保证电路长期稳定的工作,最好增加续流二极管设计,底板蜂鸣器驱动电路如下:

image.png

注:不需要蜂鸣器工作时,控制器BEEP端口输出低电平,管脚配置下拉(pull dowm)模式

蜂鸣器使用NPN三极管(S8050)驱动,三极管当开关用,当基极电压拉高时,蜂鸣器通电,当基极电压拉低时,蜂鸣器断电,FPGA控制GPIO口给三极管的基极输出不同频率的脉冲信号,蜂鸣器就可以发出不同的音节。

蜂鸣器驱动设计

前面我们了解到电磁式无源蜂鸣器需要外部提供震荡激励才可以发出声音,且震荡频率不同产生的音调也不同,不同音节与蜂鸣器震荡频率的对应关系如下表:

音调频率对照表

音节名频率(Hz)音节名频率(Hz)音节名频率(Hz)
低音1261.6中音1523.3高音11045.5
低音2293.7中音2587.3高音21174.7
低音3329.6中音3659.3高音31318.5
中音4349.2中音4698.5高音41396.9
低音5392中音5784高音51568
低音6440中音6880高音61760
低音7493.9中音7987.8高音71975.5

FPGA要驱动蜂鸣器就需要给蜂鸣器模块输出《音调频率对照表》中不同频率的脉冲信号就可以了,我们在基础数字电路实验中学习过PWM产生原理,设计过一个PWM信号发生器模块,模块根据两个输入信号(cycle、duty)控制产生周期可控、占空比可控的脉冲信号(pwm_out),可以用来驱动无源蜂鸣器电路。

PWM模块端口程序如下:

module PWM #(parameter	WIDTH = 32	//ensure that 2**WIDTH > cycle)(input					clk,input					rst_n,input		[WIDTH-1:0]	cycle,	//cycle > dutyinput		[WIDTH-1:0]	duty,	//duty < cycleoutput	reg				pwm_out);
  • cycle:基于系统时钟的计数器计数终值,与产生脉冲信号的周期有关
  • duty:脉冲信号产生机制中的比较器阈值,与产生脉冲信号的脉宽(占空比)有关

驱动蜂鸣器的脉冲信号对占空比没有太高的要求,我们默认产生50%占空比的脉冲信号,所以duty的输入取cycle的一半;cycle的值关乎蜂鸣器的音节,需要和《音调频率对照表》中对应,例如如果要蜂鸣器发出低音1的音节,脉冲信号频率控制为261.6Hz,系统时钟采用12MHz,计数器计数终值cycle就等于12M / 261.6 = 45872,即当我们给PWM模块中cycle信号的值为45872时,得到低音1的音节输出。这样我们将每个音节对应的cycle值计算出来,当按动不同按键时给PWM模块不同的cycle值就可以了,我们可以通过设计一个转码模块(tone)将按键信息转换成PWM需要的cycle信号,矩阵键盘共有16个按键,我们只能输出16个音节。

PWM周期转码程序实现如下:

always@(key_in) begin
	case(key_in)
		16'h0001: cycle = 16'd45872;	//L1,
		16'h0002: cycle = 16'd40858;	//L2,
		16'h0004: cycle = 16'd36408;	//L3,
		16'h0008: cycle = 16'd34364;	//L4,
		16'h0010: cycle = 16'd30612;	//L5,
		16'h0020: cycle = 16'd27273;	//L6,
		16'h0040: cycle = 16'd24296;	//L7,
		16'h0080: cycle = 16'd22931;	//M1,
		16'h0100: cycle = 16'd20432;	//M2,
		16'h0200: cycle = 16'd18201;	//M3,
		16'h0400: cycle = 16'd17180;	//M4,
		16'h0800: cycle = 16'd15306;	//M5,
		16'h1000: cycle = 16'd13636;	//M6,
		16'h2000: cycle = 16'd12148;	//M7,
		16'h4000: cycle = 16'd11478;	//H1,
		16'h8000: cycle = 16'd10215;	//H2,
		default:  cycle = 16'd0;		//cycle为0,PWM占空比为0,低电平
	endcaseend

现在我们在Beeper模块中实例化tone和PWM模块,将tone的输出与PWM的cycle输入连线就实现了按键信息产生对应音节的输出了,想一想逻辑有问题吗?

  • 当我们按下按键,会得到按键信息,根据按键信息转码得到一个cycle值,连线传输给PWM模块,产生对应频率脉冲,听到对应音节输出;
  • 当我们松开按键,同样有按键信息,对应到转码模块中得到cycle值为0,连线传输给PWM模块,产生低电平信号,蜂鸣器不发声。

应该没错了,到这里我们就完成了蜂鸣器音节驱动部分。

系统总体实现

前次实验中我们学习了矩阵键盘的驱动原理及方法,这里就不再重复,不一样的是之前我们用的矩阵键盘模块的脉冲输出(keypulse),本实验中简易电子琴在按键按下状态下一直发声,跟按键时间长短有关,这样我们就不能使用keypulse了,而应该使用keyout信号,另外keyout按键有效输出为低电平,而PWM周期转码模块(tone)是高有效编码,所以在顶层模块(ElectricPiano)中矩阵键盘(ArrayKeyBoard)与蜂鸣器音节驱动模块(Beeper)之间的key_out连线需要做按位取反操作。

总体设计程序实现如下:

//Array_KeyBoard Array_KeyBoard u1(.clk					(clk			),.rst_n					(rst_n			),.col					(col			),.row					(row			),.key_out				(key_out		),.key_pulse				(key_pulse		)); //beeper moduleBeeper u2(.clk					(clk			),.rst_n					(rst_n			),.key_out				(~key_out		),.beeper					(beeper			));

综合后的设计框图如下:

image.png




评论


相关推荐

技术专区

关闭