音乐倒数计数器ds.docx
《音乐倒数计数器ds.docx》由会员分享,可在线阅读,更多相关《音乐倒数计数器ds.docx(32页珍藏版)》请在冰豆网上搜索。
音乐倒数计数器ds
黄河科技学院
课程设计报告书
题目:
音乐倒数计数器
课程:
单片机课程设计
专业:
数控技术
班级:
学号:
学生姓名:
指导教师:
何春霞
2013年01月6日
摘要
本设计是基于AT89C52单片机的音乐倒数计数器,根据单片机技术原理,通过硬件电路设计与软件设计,制作出的音乐倒数计数器能稳定运行,并能正常播放音乐。
该设计硬件部分主要包括按键电路、复位电路、LCD显示电路以及蜂鸣器组成,其中K1键作为第二功能键加入外部中断0,用以切换时间选择模式。
计数值为零时,通过定时器T1调节音频,是蜂鸣器发出不同的音调。
本设计利用KeiluVision4作为编程软件进行源程序设计及调试,同时使用PROTEUS7.7进行硬件电路的搭建仿真。
关键字:
单片机音乐计数器proteus蜂鸣器
目录
1任务提出与方案论证7
1.1采用555定时器7
1.2采用单片机控制.............7
2总体设计8
2.1系统硬件设计8
2.2系统软件设计8
3详细设计及仿真9
3.1硬件电路详细设计9
3.2软件详细设计12
3.3系统仿真.......................................................14
4总结16
参考文献17
附录...............................................................18
1任务提出与方案论证
21世纪电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,而作为创新的倒数计数器更是在普通家庭中广泛应用。
1.1采用555定时器
555定时器是一种模拟和数字功能相结合的中规模集成器件。
555定时器的功能主要由两个电压比较器决定。
两个电压比较器的输出电压控制RS触发器和放电管的状态。
在
电源与地之间加上电压,当5脚悬空时,则电压比较器A1的反相输入端的电压为2VCC/3,A2的同相输入端的电压为VCC/3.若触发输入端TR的电压小于VCC/3,则比较器A2的输出为1,可使RS触发器置1,使输出端OUT=1.如果阈值输入端TH的电压大于2VCC/3,同时TR端的电压大于VCC/3,则A1的输出为1,A2的输出为0,可将RS触发器置0,使输出为0电平。
本方案由于555定时器回差太小、且不能调整、功能上有所欠缺等缺点不宜选择。
1.2采用单片机控制
单片机具有性能高、速度快、体积小、价格低、稳定可靠、应用广泛、通用性强等突出优点。
它在硬件结构、指令系统、I/O端口、功率消耗及可靠性等方面均有其独特之处,其最显著的特点之一就是具有非常有效的控制功能。
而LED显示器具有体积小、重量轻、工作电压低、功耗极低、稳定可靠、成本低、控制驱动方便、接口简单易用、模块化结构紧凑等特点,同时外接的继电器可以完成对大电流的控制,功能更加全面。
这个方案价格便宜,编程简单,专用性强,功能可随着单片机的选择而调整,比较适合本设计
综上所述,方案1.2有很大的优势,可以利用单片机和LCD显示器来实现定时倒数,通过蜂鸣器来发出音乐。
2总体设计
2.1系统硬件设计
以AT89C52单片机作为主控制器,外加按键电路、复位电路、LCD显示电路和蜂鸣器构成。
其系统框图如下:
2.2系统软件设计
本设计将各个功能部分分别封装为函数,故在主函数只需进行相关的初始化即可。
在主函数的大循环中设置播放音乐的标志位FLAG_M,在while
(1)不断检测FLAG_M是否为真,若为真,表示定时时间已到,播放预先设置的音乐-----千年之恋。
其主函数框图如下:
3详细设计及仿真
在本设计中利用了单片机的两个外部中断,以及定时器T0/T1,使得电路在运行的过程中更加灵敏及稳定。
软件的设计上将各功能封装成函数,便于调用和调试。
最后用proteus7.7搭建电路仿真,系统能正常运行。
3.1硬件电路详细设计
3.1.1AT89C52单片机
AT89C52是一个低电压,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。
如图1所示:
图1
3.1.2LCD1602液晶显示电路设计与原理
工业字符型液晶,能够同时显示16x02即32个字符(16列2行)。
1602字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源。
VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样。
1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:
阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。
Proteus7.7中的1602液晶只有14个引脚,少了背光电源的两根引脚,完全兼容。
本设计中,液晶的数据口与单片机的P0口相连。
如图2所示:
图2
3.1.3复位电路
当MCS-5l系列单片机的复位引脚RST(全称RESET)出现2个机器周期以上的高电平时,单片机就执行复位操作。
如果RST持续为高电平,单片机就处于循环复位状态。
上电复位要求接通电源后,自动实现复位操作。
当单片机已在运行当中时,按下复位键后松开,也能使RST为一段时间的高电平,从而实现上电或开关复位的操作。
如图3所示:
图3
3.1.4按键电路
题目中要求通过按键来设置定时的时间,并且能为1~60间的任意时间,根据要求以K1作为第二功能选择位,来更改时间设置的模式。
不按K1时,按下K2、K3、K4分别为定时5分钟,10分钟,20分钟;按下K1后,初始为30分钟(为方便上下调节选择30为初始值),然后再按K2为加1分钟,按K3为减1分钟,按K4为设置完成。
为了系统能更加灵敏的工作,加按键均加入了中断若有按键按下,系统能立即反应,并执行相应中断服务子程序。
K1连接外部中断0,K2,K3,K4通过一个三输入与门连接至外部中断1,并分别连接PI.0,PI.1,PI.2口,供中断服务子程序查询。
如图4所示:
图4
3.1.5蜂鸣器
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。
;蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。
蜂鸣器在电路中用字母“H”或“HA”表示。
单片机驱动他激蜂鸣器的方式有两种:
一种是PWM输出口直接驱动,另一种是利用I/O定时翻转电平产生驱动波形对蜂鸣器进行驱动。
本设计选择利用I/O定时翻转电平产生驱动波形对蜂鸣器进行驱动。
利用I/O定时翻转电平来产生驱动波形的方式必须利用定时器来做定时,通过定时翻转电平产生符合蜂鸣器要求的频率的波形,这个波形就可以用来驱动蜂鸣器了。
比如为2500Hz的蜂鸣器的驱动,可以知道周期为400μs,这样只需要驱动蜂鸣器的I/O口每200μs翻转一次电平就可以产生一个频率为2500Hz,占空比为1/2duty的方波,再通过三极管放大就可以驱动这个蜂鸣器了。
由于蜂鸣器的工作电流一般比较大,以致于单片机的I/O口是无法直接驱动的,所以要利用放大电路来驱动,一般使用三极管来放大电流就可以了。
如图5所示:
图5
3.2软件详细设计
在本程序中设置了两个标志位FLAG_M,FLAG,分别作为音乐播放标志位和时间设置模式选择标志位。
若FLAG=1,再由外部触发检测K2~K4的状态,
if(K2==0){TIME_M++;LCD_display(TIME_M,0);}
if(K3==0){TIME_M--;LCD_display(TIME_M,0);}
if(K4==0){FLAG=0;LCD_display(TIME_M,0);}
TIME_M为所定时的时间
若FLAG=0,if(K2==0){temp=5;LCD_display(5,0);}
if(K3==0){temp=10;LCD_display(10,0);}
if(K4==0){temp=20;LCD_display(20,0);}
TIME_M=temp;
本程序设计关键以及难点在于实现音乐的播放,以下详细解释用程序实现播放音乐的过程。
3.2.1音调、节拍以及编码的确定方法
一般说来,单片机演奏音乐基本都是单音频率,它不包含相应幅度的谐波频率,也就是说不能像电子琴那样能奏出多种音色的声音。
因此单片机奏乐只需弄清楚两个概念即可,也就是“音调”和节拍表示一个音符唱多长的时间。
3.2.2音调的确定
不同音高的乐音是用C、D、E、F、G、A、B来表示,这7个字母就是音乐的音名,它们一般依次唱成DO、RE、MI、FA、SO、LA、SI,即唱成简谱的1、2、3、4、5、6、7,相当于汉字“多来米发梭拉西”的读音,这是唱曲时乐音的发音,所以叫“音调”,即Tone。
把C、D、E、F、G、A、B这一组音的距离分成12个等份,每一个等份叫一个“半音”。
两个音之间的距离有两个“半音”,就叫“全音”。
在钢琴等键盘乐器上,C–D、D–E、F–G、G–A、A–B两音之间隔着一个黑键,他们之间的距离就是全音;E–F、B–C两音之间没有黑键相隔,它们之间的距离就是半音。
通常唱成1、2、3、4、5、6、7的音叫自然音,那些在它们的左上角加上﹟号或者b号的叫变化音。
﹟叫升记号,表示把音在原来的基础上升高半音,b叫降记音,表示在原来的基础上降低半音。
例如高音DO的频率(1046Hz)刚好是中音DO的频率(523Hz)的一倍,中音DO的频率(523Hz)刚好是低音DO频率(266Hz)的一倍;同样的,高音RE的频率(1175Hz)刚好是中音RE的频率(587Hz)的一倍,中音RE的频率(587Hz)刚好是低音RE频率(294Hz)的一倍。
1)要产生音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。
利用定时器计时这半个周期时间,每当计时到后就将输出脉冲的I/O反相,然后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。
2)利用AT89C51的内部定时器使其工作在计数器模式1下,改变计数值TH1及TL1以产生不同频率的方法。
此外结束符和休止符可以分别用代码00H和FFH来表示,若查表结果为00H,则表示曲子终了;若查表结果为FFH,则产生相应的停顿效果。
3)例如频率为523Hz,其周期T=1/523=1912us,因此只要令计数器计时956us/1us=956,在每次技术956次时将I/O反相,就可得到中音DO(523Hz)。
计数脉冲值与频率的关系公式如下:
N=Fi
2
Fr
N:
计算值;Fi:
内部计时一次为1us,故其频率为1MHz;
4)其计数值的求法如下:
T=65536-N=65536-Fi
2
Fr
例如:
设K=65536,F=1000000=Fi=1MHz,球低音DO(261Hz)。
中音DO(523Hz)。
高音的DO(1046Hz)的计算值
T=65536-N=65536-Fi
2
Fr=65536-1000000
2
Fr=65536-500000/Fr
低音DO的T=65536-500000/262=63627
低音DO的T=65536-500000/523=64580
低音DO的T=65536-500000/1047=65059
3.2.3节拍的确定
若要构成音乐,光有音调是不够的,还需要节拍,让音乐具有旋律(固定的律动),而且可以调节各个音的快满度。
“节拍”,即Beat,简单说就是打拍子,就像我们听音乐不自主的随之拍手或跺脚。
若1拍实0.5s,则1/4拍为0.125s。
至于1拍多少s,并没有严格规定,就像人的心跳一样,大部分人的心跳是每分钟72下,有些人快一点,有些人慢一点,只要听的悦耳就好。
音持续时间的长短即时值,一般用拍数表示。
休止符表示暂停发音。
一首音乐是由许多不同的音符组成的,而每个音符对应着不同频率,这样就可以利用不同的频率的组合,加以与拍数对应的延时,构成音乐。
了解音乐的一些基础知识,我们可知产生不同频率的音频脉冲即能产生音乐。
对于单片机来说,产生不同频率的脉冲是非常方便的,利用单片机的定时/计数器来产生这样的方波频率信号。
因此,需要弄清楚音乐中的音符和对应的频率,以及单片机定时计数的关系。
3.2.4编码
doremifasolasi分别编码为1~7,重音do编为8,重音re编为9,停顿编为0。
播放长度以十六分音符为单位(在本程序中为165ms),一拍即四分音符等于4个十六分音符,编为4,其它的播放时间以此类推。
音调作为编码的高4位,而播放时间作为低4位,如此音调和节拍就构成了一个编码。
以0xff作为曲谱的结束标志。
举例1:
音调do,发音长度为两拍,即二分音符,将其编码为0x18。
举例2:
音调re,发音长度为半拍,即八分音符,将其编码为0x22
歌曲播放的设计。
先将歌曲的简谱进行编码,储存在一个数据类型为unsignedchar的数组中。
程序从数组中取出一个数,然后分离出高4位得到音调,接着找出相应的值赋给定时器0,使之定时操作蜂鸣器,得出相应的音调;接着分离出该数的低4位,得到延时时间,接着调用软件延时。
表4.4简谱对应的简谱码、T值、节拍数
简谱
发音
简谱码
T值
节拍码
节拍数
5
低音SO
1
64260
1
1/4拍
6
低音LA
2
64400
2
2/4拍
7
低音TI
3
64524
3
3/4拍
1
中音DO
4
64580
4
1拍
2
中音RE
5
64684
5
1又1/4拍
3
中音MI
6
64777
6
1又1/2拍
4
中音FA
7
64820
8
2拍
5
中音SO
8
64898
A
2又1/2拍
6
中音LA
9
64968
C
3拍
7
中音TI
A
65030
F
3又3/4拍
1
高音DO
B
65058
2
高音RE
C
65110
3
高音MI
D
65157
4
高音FA
E
65178
5
高音SO
F
65217
3.3系统仿真
根据前面的硬件、软件的设计,在proteus7.7上进行仿真试验,结果显示系统一切运行正常。
系统硬件设计的总电路图如下:
单片机上电复位后,显示如下:
不按K1,直接按K2时,显示:
按下K1后,再按K2,显示:
按下复位按键后,显示:
系统复位了
当计数值为0时,蜂鸣器也能放出音乐。
经测试,本设计完全能够正常工作,完成了各项要求。
4总结
课程设计是培养学生综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实践能力的重要环节。
在本次设计中遇到了很多问题,特别是程序细节上的问题,但只要自己能沉下心来认真、细心、耐心的去调试程序,最后所有的问题便一个一个均迎刃而解,这也让我认识到,在项目设计的过程中一定要经的住问题的考验,只要我们认真仔细的排查问题的原因,最终还是能够解决的。
总之,这次设计从软件编写、调试到软硬件联机调试,我倾注了大量的时间和心血,当然也收获了很多。
在此认识到,要学好硬件或软件,一定要踏实下来做项目,这样我们的收获才是最大的,最直接的。
参考文献
[1]谭浩强.C程序设计[M].北京:
清华大学出版社2008
[2]郭天祥.51单片机C语言教程[M].北京:
电子工业出版社2011
[3]张毅刚.单片机原理及应用[M].北京:
高等教育出版社2011
[4]康华光.电子技术基础(模拟部分)[M].北京:
高等教育出版社2009
附录
源程序代码:
#include
#defineucharunsignedchar
#defineuintunsignedint
//特殊功能位声明
sbitK2=P1^0;
sbitK3=P1^1;
sbitK4=P1^2;
sbitLRS=P1^3;
sbitLEN=P1^4;
sbitfm=P1^5;
//全局变量声明
ucharFLAG,FLAG_M;
ucharTIME_M,TIME_S;
ucharnum;
uchartime_l,time_h;
//函数声明
voidInit_break();
voidInit_T0();
voidInit_T1();
voidInit_LCD();
voidLCD_W_cmd(uchar);
voidLCD_W_data(uchar);
voidLCD_display(uchar,uchar);
voidFLAG_0();
voidFLAG_1();
voiddelay(uint);
voiddelay16(uint);
voidPLAY_MUSIC();
/////////////////////////////////////////////////////
ucharcodetable_name[]="ZhengLi";
///////////////////////////////////////////////////////
//---------------------------简谱---------------------------------------
//编程规则:
字节高位是简谱,低位是持续时间,
//代表多少个十六分音符
//1-7代表中央C调,8-E代表高八度,0代表停顿
//最后的0是结束标志
ucharcodeqnzl[]={//千年之恋
0x12,0x22,0x34,0x84,0x74,0x54,0x38,0x42,0x32,0x22,0x42,0x34,0x84,0x72,0x82,0x94,0xA8,0x08,
//前奏
0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62,
//竹林的灯火到过的沙漠
0x32,0x31,0x21,0x32,0x82,0x71,0x81,0x71,0x51,0x32,0x22,
//七色的国度不断飘逸风中
0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62,
//有一种神秘灰色的旋涡
0x32,0x31,0x21,0x32,0x83,0x82,0x71,0x72,0x02,
//将我卷入了迷雾中
0x63,0xA1,0xA2,0x62,0x92,0x82,0x52,
//看不清的双手
0x31,0x51,0x63,0x51,0x63,0x51,0x63,0x51,0x62,0x82,0x7C,0x02,
//一朵花传来谁经过的温柔
0x61,0x71,0x82,0x71,0x62,0xA2,0x71,0x76,
//穿越千年的伤痛
0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36,
//只为求一个结果
0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53,
//你留下的轮廓指引我
0x42,0x63,0x83,0x83,0x91,0x91,
//黑夜中不寂寞
0x61,0x71,0x82,0x71,0x62,0x0A2,0x71,0x76,
//穿越千年的哀愁
0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36,
//是你在尽头等我
0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53,
//最美丽的感动会值得
0x42,0x82,0x88,0x02,0x74,0x93,0x89,0xff//结束标志
//用一生守候
};
//----------------------------简谱音调对应的定时器初值---------------------------
//适合11.0592M的晶振
ucharcodeT1_cuzhi[]={
0xff,0xff,//占位
0xFC,0x8E,//中央C调1-7
0xFC,0xED,
0xFD,0x43,
0xFD,0x6A,
0xFD,0xB3,
0xFD,0xF3,
0xFE,0x2D,
0xFE,0x47,//高八度1-7
0xFE,0x76,
0xFE,0xA1,
0xFE,0xC7,
0xFE,0xD9,
0xFE,0xF9,
0xFF,0x16
};
/************************************************
****************主函数**************************/
voidmain()
{
Init_break();
Init_T0();
Init_T1();
Init_LCD();
LCD_display(0,0);
//PLAY_MUSIC();
while
(1)
{
if(FLAG_M==1)
PLAY_MUSIC();
}
}
/****************************************************
******************外部中断**************************/
voidInit_break()//外部中断初始化
{
EA=1;
EX0=1;
EX1=1;
IT0=1;
IT1=1;
}
voidExtern0()interrupt0
{
FLAG=1;
TIME_M=30;//设置初始化为30,便于上下调节
LCD_display(TIME_M,0);
}
voidExtern1()interrupt2
{
if(FLAG==1)
FLAG_1();
else
FLAG_0();
}
voidFLAG_0()
{
uchartemp;
if(K2==0)
{
temp