任务5.10蜂鸣器和音乐发生器_第1页
任务5.10蜂鸣器和音乐发生器_第2页
任务5.10蜂鸣器和音乐发生器_第3页
任务5.10蜂鸣器和音乐发生器_第4页
任务5.10蜂鸣器和音乐发生器_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、5.10 蜂鸣器和音乐发生器任务5.10 蜂鸣器的原理和驱动5.9.1 任务介绍在实际应用中,经常利用利用单片机控制蜂鸣器产生各种音乐用于报警和提示,如手机的铃声、时钟的音乐报时和按键提示音等。本节的任务是:通过单片机I/O控制开发板上的蜂鸣器演奏音乐。5.9.2 知识准备1、 蜂鸣器的原理和分类蜂鸣器按结构分有压电式蜂鸣器和电磁式蜂鸣器两种类型。压电蜂鸣器内部有压电陶瓷和金属片,是利用压电陶瓷的压电效应,带动金属片的振动来发声,频率在1KHz10KHz。电磁式蜂鸣器内部有磁铁和线圈,振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声,频率在0.5KHz5KHz。压电蜂鸣器结构简单耐用,声

2、音大,多用于报警器等设备。电磁蜂鸣器音色好,多用于语音、音乐等设备。蜂鸣器按其是否带有振荡器又分为有源和无源两种类型。有源蜂鸣器内部带有振荡器,只需要在其供电端加上额定直流电压,其内部的振荡器就可以产生固定频率的信号,驱动蜂鸣器发出声音。无源蜂鸣器内部没有振荡器,需要在其供电端上加上高低不断变化的电信号才可以驱动发出声音。开发板上的蜂鸣器属于电磁式无源蜂鸣器。2、 开发板蜂鸣器驱动电路开发板蜂鸣器驱动电路如图5.10.1所示。5.10.1 开发板蜂鸣器驱动电路蜂鸣器的驱动和继电器相似,需要几十mA的电流,通常借助于三极管来作为中间功率驱动。图5.10.1中,蜂鸣器接在PNP三极管(8550)的

3、集电极上,单片机I/O接三极管的基极,电阻R10是三极管基极限流电阻,电阻R11是上拉电阻。蜂鸣器内部线圈是感性器件,二极管D10并联在蜂鸣器两端,起到限制反峰电压的作用。3、无源蜂鸣器的程序驱动无源蜂鸣器本身不带振荡器,只有让蜂鸣器不停的处于“通电-断电”的状态,才能发出声音。对于开发板上蜂鸣器驱动电路而言,只需要让控制蜂鸣器的I/O口不停的“置1-置0”就可以了。下面是利用51单片机P.20驱动蜂鸣器的程序。#incldue<reg52.h>#define uchar unsigned char#define uint unsigend intsbit Buzzer=P20;

4、/蜂鸣器接口定义#define BuzzerOn Buzzer=0#define BuzzerOff Buzzer=1 /ms级延时函数void DelayMs(uint xms) uint i,j; for(i=0;i<xms;i+) for(j=0;j<122;j+);/主函数void main() while(1) BuzzerOn; DelayMs(1); BuzzerOff DelayMs(1); 在程序中,1ms让蜂鸣器通电,1ms让蜂鸣器断电,频率500Hz。程序编译下载后,蜂鸣器引脚控制端接P2.0引脚,蜂鸣器发出“嗡嗡”的声音。然后在把延时改为2ms、3ms、5m

5、s,蜂鸣器会发出不同频响的声音。4、蜂鸣器程序改造和按键提示音利用延时函数来驱动蜂鸣器显然不是个好的办法,下面的程序通过定时器驱动蜂鸣器,开发板上2个独立按键,每个按键按下时,蜂鸣器响一声,持续时间为0.3秒。2个按键对应的频率分别为500Hz和1KHz。要求程序不堵塞CPU,效率高。(1) 工程结构和主函数工程结构图如图5.10.2所示。除了主函数外,还有按键模块、定时器模块和键值处理模块。 图5.10.2 工程结构图主函数如下:#include<reg52.h>#include"MicroDefine.h"#include"Timer.h"

6、;#include"IndependentKey.h"#include"KeyProcess.h" /*函数名称:main()*功能 :主函数*入口参数:无*出口参数:无*说明 :按键被按下时,蜂鸣器产生0.5S提示音。 按键A提示音频率:500Hz 按键B提示音频率:1KHz */void main() uchar KeyValue=0; DelayMs(200); TimerInit(); /定时器初始化 while(1) if(FlagSystem1Ms=1) /1ms时标信号 FlagSystem1Ms=0; KeyValue=KeyGetVal

7、ue(); /获取键值 KeySound(KeyValue); /键值处理 程序解释:主函数内容简单,获取按键键值,并处理键值。(2) 其它功能模块 定时器模块(Timer.c,Timer.h不列出)#include"Timer.h"bit FlagSystem1Ms=0; /1m时标信号uchar T1High=0; /T0高8位uchar T1Low=0; /T1低8位/*函数名称:TimerInit()*功能 :定时器初始化*入口参数:无*出口参数:无*说明 :定时器0:产生1ms时标信号,方式2 定时器1:驱动蜂鸣器,方式1*/void TimerInit() TM

8、OD=0x12; TH0=TL0=56; TH1=TL1=0; TR0=1; /只开定时器0,定时器1的开启由按键决定ET0=ET1=1; EA=1;TR0=1; /开定时器0,TR1=0; /定时器1关闭 ,按键按下,才能开定时器1/*函数名称:Timer0Isr()*功能 :定时器0中断服务函数*入口参数:无*出口参数:无*说明 :*/void Timer0Isr() interrupt 1 static uchar Cnt200us=0; if(+Cnt200us<=5) /产生1ms时标信号 Cnt200us=0; FlagSystem1Ms=1; /*函数名称:Timer1Is

9、r()*功能 :定时器1中断服务函数*入口参数:无*出口参数:无*说明 :通过改变定时器的初装值,产生不同频率的蜂鸣器驱动信号*/void Timer1Isr() interrupt 3 TH1=T1High; /加载初值,键值处理模块设置初值 TL1=T1Low; Buzzer=Buzzer; /电平反转程序解释:使用了2个定时器,定时器0用来产生1ms时标信号,定时器1用来驱动蜂鸣器。在定时器初始化中,定时器1配置好后,先不开定时器1,只有按键按下后,才能开定时器1。定时器1使用了方式1(16位),每一次溢出后,在中断服务函数中,手动重装初值,初值的大小由键值处理模块给定。在中断服务函数中

10、,实现蜂鸣器驱动I/O的电平反转。 键值处理模块(KeyProcess.h)#include"KeyProcess.h"/*函数名称:KeySound()*功能 :按键提示音*入口参数:按键值*出口参数:无*说明 :*/void KeySound(uchar KeyValue) static uchar SoundState=0; /状态机变量 static uint Cnt1Ms=0; /1ms计数器 switch(SoundState) case 0: /状态0:按键被按下,开定时器1 if(KeyValue=0x81) /按键A被按下,蜂鸣器响 T1High=0xFC

11、; /定时器1初值,输出500Hz方波 T1Low=0x18; TH1=0xFF; /让定时器快速完成第一次溢出, TL1=0xFF; TR1=1; /开定时器 SoundState=1; /跳转到状态0 if(KeyValue=0x82) /按键B被按下,蜂鸣器响 T1High=0xFE; T1Low=0x0c; TH1=0xFF; TL1=0xFE; SoundState=1; TR1=1; break; case 1: /状态1:延时299ms,关闭蜂鸣器 if(+Cnt1Ms>=299) Cnt1Ms=0; TR1=0; /关闭定时器,蜂鸣器不响 SoundState=0; /跳

12、转到状态0 程序解释:KeySound()由状态机构成,分成两个状态。状态0:检测到按键被按下,根据按键值,给定时器赋初值,并启动定时器。状态1:延时299ms后,关闭定时器1,并返回到状态0。利用状态机构成按键提示音函数,不堵塞CPU,系统效率高。5.9.3 任务实施1、 音符和频率的关系通过以上知识的学习,初学者了解到蜂鸣器发声的原理,即通过I/O口输出脉冲信号,再将信号通过三极管放大,推动发声器件(蜂鸣器)发声。脉冲信号的频率不同,蜂鸣器发出的声音不同。要完成本节的音乐播放器,需弄清楚两个概念即可,也就是“音符”和“节拍”。音符其实就是我们常说的“Do Re Mi Fa Sol La S

13、i Do”,每一个音符对应一定的频率。以中音“1”为例,其频率为523Hz,周期为1秒/523=1912us,半周期为956us。通常没有做特殊说明,我们把音乐的一个节拍的时间长度定位0.4秒,1/4节拍的时间则为0.1秒。如果以1/4节拍为基准长度,则1拍为4个基准长度,1/2拍为2个基准长度。定时器要产生中音“1”对应的频率(523Hz),则定时器每次溢出的时间为半个周期(即956us)。假设中音“1”的时间长度为1/4拍,则定时器溢出的次数为0.1秒/956us=105次。1/2拍和1拍对应的溢出次数分别105次*2和105次*4。为了程序的方便,我们把低音音符(“5 ”“7”)、中音音

14、符(“1”“7”)和高音音符(“ ”“”)的频率、半周期及1/4节拍内半周期数放在表5.10.1中。表5.10.1 14个音符频率对应表数组下标音符频率(Hz)周期(us)半周期(us)1/4节拍(0.1S)内半周期数的个数05392255112767816440227311368827494202410129931523191295610542587107485111753659151775813264698143671614075783127763815786880113656817697988101250619810104695647820911117585142523512131875

15、9379264根据表5.10,我们先构建两个数组,分别存放以上音符的半周期时间和1/4拍内半周期的个数。/13个音符的半周期长度uchar code TableNoteTime=1276,1136,1012,956,851,758,716,638,568,506,478,425,379;/13个音符1/4拍内半周期的个数uchar code TableNoteNum=78,88,99,105,117,132,140,157,176,198,209,235,264;图5.10.3是儿童歌曲“两支老虎”的简谱。 图5.10.3 “两只老虎”简谱根据简谱,我们把简谱中对应的音符和其拍数再分别放到数组

16、中。需要说明的是,该数组元素和简谱中音符的对应关系,例如音符“1”,在数组TableNoteTime中是第4个元素,所以在音乐简谱数组中应写为“3”。拍数以1/4拍为基本单位,拍数数组中元素的“1”、“2”和“4”分别对应音符的1/4拍、1/2拍和1拍。/简谱中对应的音符uchar code TableMusicNote=3,4,5,3,3,4,5,3,5,6,7,5,6,7,7,8,7,6,5,3,7,8,7,6,5,3,4,0,3,4,0,3;/简谱中音符对应的拍数uchar code TalbeMusicBeat=2,2,2,2,2,2,2,2,2,2,4,2,2,4,1,1,1,1,2

17、,2,1,1,1,1,2,2,2,2,4,2,2,4;有了这4个数组,音乐播报就变得简单了。根据TableMusicNote数组中的值,从TableNoteTime数组中找到待播放音符的半周期长度,将半周期长度作为定时器的溢出值,启动定时器,蜂鸣器就会产生该音符。在播报音符的同时,根据TableMusicNote数组中的值,从TableNoteNum数组中找到该音符所对应的1/4拍内半周期的个数,然后再从TalbeMusicBeat数组中,找到该音符在简谱中的拍数,两者相乘,即为定时器产生该音符所对应频率的时间长度。播报完了第一个音符,然后再播报第二个音符.直到最后一个音符,一首曲子就播放完了

18、。2、 程序实现(1) 工程架构和主函数程序的工程架构如图5.10.4所示。除了主函数模块,至于键值获取模块和定时器模块。音乐播放放在定时器模块中完成。图5.10。4 工程结构图主函数如下:#include<reg52.h>#include "MicroDefine.h"#include "Timer.h"#include "IndependentKey.h"/*函数名称:main()*功能 :主函数*入口参数:无*出口参数:无*说明 : */void main() uchar KeyValue=0; uchar Cnt1

19、Ms=0; DelayMs(200); TimerInit(); /定时器初始化 while(1) if(FlagSystem1Ms=1) /1ms时标信号到 FlagSystem1Ms=0; if(+Cnt1Ms>=10) /10ms时标信号到 Cnt1Ms=0; KeyValue=KeyGetValue(); /获取按键值 if(KeyValue=0x81) if(FlagMusicEnd=0) /上一次播放完毕,则启动新的播放 TR1=1; /启动定时器 FlagMusicEnd=1; /音乐播放中 程序解释:在主程序中检测按键按下,则启动定时器1,并把音乐结束标志位置1。(2)

20、其它功能模块 键值处理模块(省略) 定时器模块Timer.h:#ifndef _TIMER_H_#define _TIMER_H_#include<reg52.h>#include"MicroDefine.h"sbit Buzzer=P20;#define MusicPlaySpeed 20 /音乐播放速度宏定义/变量声明extern bit FlagSystem1Ms; /1m时标信号extern bit FlagMusicEnd; /音乐播放结束标志位/定时器声明extern void TimerInit(); /定时器初始化#endifTimer.c:#i

21、nclude"Timer.h"bit FlagSystem1Ms=0; /1m时标信号bit FlagMusicEnd=0; /音乐播放结束标志位 /13个音符的半周期长度uint code TableNoteTime=1276,1136,1012,956,851,758, 716,638,568,506,478,425,379;/13个音符对应的1/4拍内半周期的个数uint code TableNoteNum=78,88,99,105,117,132,140,157, 176,198,209,235,264;/简谱中对应的音符uchar code TableMusicN

22、ote=3,4,5,3,3,4,5,3,5,6,7,5,6,7,7,8, 7,6,5,3,7,8,7,6,5,3,4,0,3,4,0,3;/简谱中音符对应的拍数uchar code TalbeMusicBeat=2,2,2,2,2,2,2,2,2,2,4,2,2,4,1,1, 1,1,2,2,1,1,1,1,2,2,2,2,4,2,2,4;/*函数名称:TimerInit()*功能 :定时器初始化*入口参数:无*出口参数:无*说明 :定时器0:产生1ms时标信号,方式2 定时器1:驱动蜂鸣器, 方式1*/void TimerInit() TMOD=0x12; TH0=TL0=56; TH1=T

23、L1=0xFF; ET0=ET1=1; EA=1; TR0=1; /只开定时器0,定时器1的开启由按键决定/*函数名称:Timer0Isr()*功能 :定时器0中断服务函数*入口参数:无*出口参数:无*说明 :*/void Timer0Isr() interrupt 1 static uchar Cnt200us=0; if(+Cnt200us>=5) /产生1ms时标信号 Cnt200us=0; FlagSystem1Ms=1; /*函数名称:Timer1Isr()*功能 :定时器1中断服务函数*入口参数:无*出口参数:无*说明 :通过改变定时器的初装值,产生不同频率的蜂鸣器驱动信号

24、MusicPlaySpeed是头文件中宏定义,决定音乐的播放速度,其值不能小于10*/void Timer1Isr() interrupt 3 static uchar NoteCnt=0; /播放音符计数器 static uint HalfPeriodCnt=0; /半周期计数器 uint Timer1Temp=0; /定时器长度暂存值 /根据当前播放音符,计算出对应的定时器初值 Timer1Temp=65536-TableNoteTimeTableMusicNoteNoteCnt; TH1=Timer1Temp/256; TL1=Timer1Temp%256; Buzzer=!Buzzer; /播放一个音符的时间到 if(+HalfPeriodCnt>=(TableNoteNumTableMusicNoteNoteCnt *TalbeMusicBeatNoteCnt)*MusicPlaySpeed/10) HalfPeriodCnt=0; /简谱中的音符全部播放完 if(+NoteCnt>=32) NoteCnt=0; TR1=0; /定时器停止 FlagMusicEnd=0; /音乐播放结束结束标志位清零 程序解释:程序中使用了两个定时器,和之前按键音

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论