任务510蜂鸣器和音乐发生器Word文档下载推荐.docx
- 文档编号:20868052
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:17
- 大小:116.61KB
任务510蜂鸣器和音乐发生器Word文档下载推荐.docx
《任务510蜂鸣器和音乐发生器Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《任务510蜂鸣器和音乐发生器Word文档下载推荐.docx(17页珍藏版)》请在冰豆网上搜索。
//ms级延时函数
voidDelayMs(uintxms)
{
uinti,j;
for(i=0;
i<
xms;
i++)
for(j=0;
j<
122;
j++);
}
//主函数
voidmain()
while
(1)
{
BuzzerOn;
DelayMs
(1);
BuzzerOff
}
在程序中,1ms让蜂鸣器通电,1ms让蜂鸣器断电,频率500Hz。
程序编译下载后,蜂鸣器引脚控制端接P2.0引脚,蜂鸣器发出“嗡嗡”的声音。
然后在把延时改为2ms、3ms、5ms,蜂鸣器会发出不同频响的声音。
4、蜂鸣器程序改造和按键提示音
利用延时函数来驱动蜂鸣器显然不是个好的办法,下面的程序通过定时器驱动蜂鸣器,开发板上2个独立按键,每个按键按下时,蜂鸣器响一声,持续时间为0.3秒。
2个按键对应的频率分别为500Hz和1KHz。
要求程序不堵塞CPU,效率高。
(1)工程结构和主函数
工程结构图如图5.10.2所示。
除了主函数外,还有按键模块、定时器模块和键值处理模块。
图5.10.2工程结构图
主函数如下:
#include<
#include"
MicroDefine.h"
Timer.h"
IndependentKey.h"
KeyProcess.h"
/***************************************************************************
*函数名称:
main()
*功能:
主函数
*入口参数:
无
*出口参数:
*说明:
按键被按下时,蜂鸣器产生0.5S提示音。
按键A提示音频率:
500Hz
按键B提示音频率:
1KHz
***************************************************************************/
ucharKeyValue=0;
DelayMs(200);
TimerInit();
//定时器初始化
if(FlagSystem1Ms==1)//1ms时标信号
FlagSystem1Ms=0;
KeyValue=KeyGetValue();
//获取键值
KeySound(KeyValue);
//键值处理
程序解释:
主函数内容简单,获取按键键值,并处理键值。
(2)其它功能模块
定时器模块(Timer.c,Timer.h不列出)
bitFlagSystem1Ms=0;
//1m时标信号
ucharT1High=0;
//T0高8位
ucharT1Low=0;
//T1低8位
TimerInit()
定时器初始化
定时器0:
产生1ms时标信号,方式2
定时器1:
驱动蜂鸣器,方式1
voidTimerInit()
TMOD=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中断服务函数
voidTimer0Isr()interrupt1
staticucharCnt200us=0;
if(++Cnt200us<
=5)//产生1ms时标信号
Cnt200us=0;
FlagSystem1Ms=1;
Timer1Isr()
定时器1中断服务函数
通过改变定时器的初装值,产生不同频率的蜂鸣器驱动信号
voidTimer1Isr()interrupt3
TH1=T1High;
//加载初值,键值处理模块设置初值
TL1=T1Low;
Buzzer=~Buzzer;
//电平反转
使用了2个定时器,定时器0用来产生1ms时标信号,定时器1用来驱动蜂鸣器。
在定时器初始化中,定时器1配置好后,先不开定时器1,只有按键按下后,才能开定时器1。
定时器1使用了方式1(16位),每一次溢出后,在中断服务函数中,手动重装初值,初值的大小由键值处理模块给定。
在中断服务函数中,实现蜂鸣器驱动I/O的电平反转。
键值处理模块(KeyProcess.h)
KeySound()
按键提示音
按键值
voidKeySound(ucharKeyValue)
staticucharSoundState=0;
//状态机变量
staticuintCnt1Ms=0;
//1ms计数器
switch(SoundState)
case0:
//状态0:
按键被按下,开定时器1
if(KeyValue==0x81)//按键A被按下,蜂鸣器响
T1High=0xFC;
//定时器1初值,输出500Hz方波
T1Low=0x18;
TH1=0xFF;
//让定时器快速完成第一次溢出,
TL1=0xFF;
TR1=1;
//开定时器
SoundState=1;
//跳转到状态0
if(KeyValue==0x82)//按键B被按下,蜂鸣器响
T1High=0xFE;
T1Low=0x0c;
TL1=0xFE;
SoundState=1;
}break;
case1:
//状态1:
延时299ms,关闭蜂鸣器
if(++Cnt1Ms>
=299)
Cnt1Ms=0;
TR1=0;
//关闭定时器,蜂鸣器不响
SoundState=0;
//跳转到状态0
KeySound()由状态机构成,分成两个状态。
状态0:
检测到按键被按下,根据按键值,给定时器赋初值,并启动定时器。
状态1:
延时299ms后,关闭定时器1,并返回到状态0。
利用状态机构成按键提示音函数,不堵塞CPU,系统效率高。
5.9.3任务实施
1、音符和频率的关系
通过以上知识的学习,初学者了解到蜂鸣器发声的原理,即通过I/O口输出脉冲信号,再将信号通过三极管放大,推动发声器件(蜂鸣器)发声。
脉冲信号的频率不同,蜂鸣器发出的声音不同。
要完成本节的音乐播放器,需弄清楚两个概念即可,也就是“音符”和“节拍”。
音符其实就是我们常说的“DoReMiFaSolLaSiDo”,每一个音符对应一定的频率。
以中音“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”)、中音音符(“1”~“7”)和高音音符(“
”~“
”)的频率、半周期及1/4节拍内半周期数放在表5.10.1中。
表5.10.114个音符频率对应表
数组下标
音符
频率(Hz)
周期(us)
半周期(us)
1/4节拍(0.1S)
内半周期数的个数
5
392
2551
1276
78
1
6
440
2273
1136
88
2
7
494
2024
1012
99
3
523
1912
956
105
4
587
1074
851
117
659
1517
758
132
698
1436
716
140
783
1277
638
157
8
880
568
176
9
988
506
198
10
1046
478
209
11
1175
425
235
12
1318
759
379
264
根据表5.10,我们先构建两个数组,分别存放以上音符的半周期时间和1/4拍内半周期的个数。
//13个音符的半周期长度
ucharcodeTableNoteTime[]={1276,1136,1012,956,851,758,716,638,568,506,478,425,379};
//13个音符1/4拍内半周期的个数
ucharcodeTableNoteNum[]={78,88,99,105,117,132,140,157,176,198,209,235,264};
图5.10.3是儿童歌曲“两支老虎”的简谱。
图5.10.3“两只老虎”简谱
根据简谱,我们把简谱中对应的音符和其拍数再分别放到数组中。
需要说明的是,该数组元素和简谱中音符的对应关系,例如音符“1”,在数组TableNoteTime[]中是第4个元素,所以在音乐简谱数组中应写为“3”。
拍数以1/4拍为基本单位,拍数数组中元素的“1”、“2”和“4”分别对应音符的1/4拍、1/2拍和1拍。
//简谱中对应的音符
ucharcodeTableMusicNote[]={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};
//简谱中音符对应的拍数
ucharcodeTalbeMusicBeat[]={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};
有了这4个数组,音乐播报就变得简单了。
根据TableMusicNote[]数组中的值,从TableNoteTime[]数组中找到待播放音符的半周期长度,将半周期长度作为定时器的溢出值,启动定时器,蜂鸣器就会产生该音符。
在播报音符的同时,根据TableMusicNote[]数组中的值,从TableNoteNum[]数组中找到该音符所对应的1/4拍内半周期的个数,然后再从TalbeMusicBeat[]数组中,找到该音符在简谱中的拍数,两者相乘,即为定时器产生该音符所对应频率的时间长度。
播报完了第一个音符,然后再播报第二个音符...直到最后一个音符,一首曲子就播放完了。
2、程序实现
(1)工程架构和主函数
程序的工程架构如图5.10.4所示。
除了主函数模块,至于键值获取模块和定时器模块。
音乐播放放在定时器模块中完成。
图5.10。
4工程结构图
#include"
ucharCnt1Ms=0;
if(FlagSystem1Ms==1)//1ms时标信号到
=10)//10ms时标信号到
//获取按键值
if(KeyValue==0x81)
if(FlagMusicEnd==0)//上一次播放完毕,则启动新的播放
//启动定时器
FlagMusicEnd=1;
//音乐播放中
}
在主程序中检测按键按下,则启动定时器1,并把音乐结束标志位置1。
键值处理模块(省略)
定时器模块
Timer.h:
#ifndef_TIMER_H_
#define_TIMER_H_
#defineMusicPlaySpeed20//音乐播放速度宏定义
//变量声明
externbitFlagSystem1Ms;
externbitFlagMusicEnd;
//音乐播放结束标志位
//定时器声明
externvoidTimerInit();
#endif
Timer.c:
bitFlagMusicEnd=0;
//音乐播放结束标志位
uintcodeTableNoteTime[]={1276,1136,1012,956,851,758,\
716,638,568,506,478,425,379};
//13个音符对应的1/4拍内半周期的个数
uintcodeTableNoteNum[]={78,88,99,105,117,132,140,157,\
176,198,209,235,264};
ucharcodeTableMusicNote[]={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};
ucharcodeTalbeMusicBeat[]={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};
驱动蜂鸣器,方式1
TH1=TL1=0xFF;
ET0=ET1=1;
if(++Cnt200us>
MusicPlaySpeed是头文件中宏定义,决定音乐的播放速度,其值不能小于10
staticucharNoteCnt=0;
//播放音符计数器
staticuintHalfPeriodCnt=0;
//半周期计数器
uintTimer1Temp=0;
//定时器长度暂存值
//根据当前播放音符,计算出对应的定时器初值
Timer1Temp=65536-TableNoteTime[TableMusicNote[NoteCnt]];
TH1=Timer1Temp/256;
TL1=Timer1Temp%256;
Buzzer=!
Buzzer;
//播放一个音符的时间到
if(++HalfPeriodCnt>
=(TableNoteNum[TableMusicNote[NoteCnt]]\
*TalbeMusicBeat[NoteCnt])*MusicPlaySpeed/10)
HalfPeriodCnt=0;
//简谱中的音符全部播放完
if(++NoteCnt>
=32)
NoteCnt=0;
//定时器停止
FlagMusicEnd=0;
//音乐播放结束结束标志位清零
程序中使用了两个定时器,和之前按键音一样,一个用来产生系统时标信号,另外一个用于用于驱动蜂鸣器。
按键启动定时器1,定时器1溢出后,从播报的第一音符起,取出该音符半周期时间长度,计算出定时器1的初值,让定时器1输出该音符对应的脉冲波。
定时器1每溢出1次,半周期计数器(HalfPeriodcnt)加1,音符播放的时间长度由半周期计数器的值来决定。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 任务510 蜂鸣器和音乐发生器 任务 510 蜂鸣器 音乐 发生器