课程设计说明书题目:基于单片机的电子琴设计院(系):电子工程与自动化学院专业:测控技术与仪器(卓越)学生姓名:学号:指导教师:2013年9月21日目录1摘要……………………………………………………………………12关键字…………………………………………………………………13设计任务及要求………………………………………………………14方案可行性论证………………………………………………………15程序框图………………………………………………………………26关键单元电路与程序介绍……………………………………………36.1复位与震荡电路………………………………………………36.24x4矩阵键盘…………………………………………………36.3数码管与LED灯………………………………………………46.4蜂鸣器…………………………………………………………66.5音乐相关知识…………………………………………………77调试过程………………………………………………………………118总结与体会……………………………………………………………119参考文献………………………………………………………………1110附录……………………………………………………………………1210.1设备与仪器……………………………………………………1210.2软件……………………………………………………………1210.3原件清单………………………………………………………1210.4原理图与PCB图………………………………………………1310.5总程序……………………………………………………………1410.6实物图……………………………………………………………31【摘要】:打造一个多功能电子琴,核心是一块单片机。单片机读取键值,为内置定时器赋初值,定时器每溢出一次,驱动蜂鸣器的引脚电平就取反一次,产生相应频率的方波,即音调;设好键值与数码管段码表的对应关系,键按下时,数码管显示对应音调。一首音乐储存在一个表中,表中的数据是音调与节拍,单片机读取音符的音调与节拍,根据音调赋予定时器初值,根据节拍决定定时器工作的时间,也就是蜂鸣器响的时间,一个接一个地读取音符,即可播放一首歌曲。节拍用led灯的点亮个数表示。单片机读取音乐表中的节拍,控制led灯的点亮个数,达到显示节拍的效果。特别要注意的是:该方案采用了两个定时器,T0、T1。T0作为驱动蜂鸣器的定时器,要给予高优先级,不然会被T1干扰,音质变差。【关键字】:单片机、stc89c52、电子琴、C51、keil。【设计任务及要求】:1.通过按键能够发出相应的音符并播放产生乐音,实现演奏;2.演奏的同时可数字显示当前的音调,利于培养乐感3.可以选定播放固定乐曲自动演奏,演奏时LED进行节拍指示;4.在自动演奏和奏乐的过程中按停止键则中断演奏;5.可以选择调节音或小。【方案可行性论证】:本课题采用stc89c52单片机作为核心器件,实现基本的音乐弹奏、音乐播放、音调显示和音乐节拍指示的功能。1.音乐弹奏:通过程序识别4x4矩阵键盘中按下的键的坐标(x,y),然后根据(x,y)从计数初值表中读取对应的计数初值,赋值给定时器0,定时器产生对应频率的方波,达到播放对应音调的功能。2.音乐播放:先建立一个包含一首音乐的音调与节拍的表。其中,音调就是0x01(低音、do)、0x12(中音、re)、0x23(高音、mi)之类的数;节拍就是0x02(半拍),0x04(一拍)之类的数。然后,根据音调读取计数初值,再将计数初值赋给定时器T0-开启定时器T0-读取节拍并延时-关闭定时器T0。这样就发出了一个音,然后再读下一个音的初值与节拍,重复上一个操作即可。(具体实现方法见附录总程序)3.数码管显示音调:①按键:读出按键坐标(x,y),用if语句来判断(x,y)该给数码管赋什么值,然后从ucharcodenum[]表中读取这个值赋给数码管(例如P0)。②播放歌曲时:读入音调,根据音调的值来判断num[i]这个表中的i,再把num[i]赋给P0口。4.led灯的节拍指示:采用定时器1来控制,作为节拍指示。①按键时:根据按下的时长来控制led的点亮个数,并且是按一定的时间间隔逐个点亮;释放按键时,led灯按一定的时间间隔逐个熄灭,从而达到一种比较简单的节拍指示效果。②播放音乐时:根据音符的节拍,控制点亮到哪一个灯,在点亮那个灯之前,前面的灯逐个等时距点亮。音符结束后,led灯全部一起熄灭。这样,达到了一个精确显示节拍的效果。【程序框图】:开始扫描键盘读取歌曲是否播放键按下有矩阵键按下否识别按键数码管显示音调算出定时器初值开启定时器,并赋初值,蜂鸣器发声按键是否释放关闭定时器P0口置0是否否算出音符的音调、节拍根据音调给T0赋初值开启T0T1按节拍延迟关闭T0T1数码管与led是否结束符否读下一个音符数码管显示音调Led指示节拍是是否停止播放是【复位与震荡电路】:原件的参数如图所示。C1,C2可采用30pF无极性陶瓷电容;C3可采用10µF记性电解质电容。值得注意的是,晶振不能随便摸!尤其在通电工作的时候,触摸容易损坏。自从摸过一次后,震荡频率变得不稳定,蜂鸣器声音时好时坏。【4x4矩阵键盘】:键盘扫描的基本思路是:先得出触发按键的“行”,即横坐标x,再得出他的“列”,即纵坐标y。以下是获取横坐标x的代码:ucharkey_x()/*P1口高位接纵坐标(P1.7-P1.4)低位接横坐标(P1.3-P1.0)*/{uchari;P1=0x0f;/*有按键按下后对应按键的横坐标电位被拉低(注意低电位引脚不能被高电位引脚抬高,只能是低电位拉低高电位)*/if(P1_0==0){delayms(5);//延时5ms去抖动if(P1_0==0)i=1;}elseif(P1_1==0){delayms(5);if(P1_1==0)i=2;}elseif(P1_2==0){delayms(5);if(P1_2==0)i=3;}elseif(P1_3==0){delayms(5);if(P1_3==0)i=4;}elsei=0;return(i);//0表示按键未按下}获取y的方法与获取x的方法类似,具体可以参考附件总程序。得到触发按键的坐标(x,y)之后,可以通过x,y的值来确定按键的功能。例如x==1,y==1时(S1按下),可以让数码管显示1:if(x==1&&y==1)P0=led_table[1];或者更方便一点:if(x==1)P0=led_table[y];就能显示第一行的所有的数了。【数码管与LED灯】:数码管:在本课题中,数码管要显示A-G,1-7,1.-7.,所以段码比较另类。num[0]的值是没用到的,起占位作用。ucharcodenum[]={0x00,//共阴极数码管段选码0x77,0x7c,0x39,0x5e,0x79,0x71,0x3d,//a-g0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,//1-70x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87//1.-7.};编写程序时,要根据实际情况来编写:比如16个按键不能够把低中高音都全部表示完全,只能选取合适的部分。我让第一行的按键触发低音4-7,第二行触发中音1-4,第三行触发中音5-7和高音1,第四行触发高音2-5。这样设置能弹奏大部分曲目。以下是控制数码管的代码片段:if(x==1)P0=num[3+y];//低音4-7elseif(x==2)P0=num[7+y];//中音1-4elseif(x==3)P0=num[11+y];//中音5-7和高音1elseif(x==4)P0=num[15+y];//高音2-5LED灯:因为LED灯要按一定的时间逐个点亮或者逐个熄灭,所以我用定时器1来控制它。定时器1每溢出一次并满足一定条件时flash变量就+1或者-1,然后从led_table[]这个表中读出相应的数赋给P2口。表:ucharcodeled_table[]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};/*发光二极管闪烁表*/代码:if(x!=0&&y!=0&&flash8)//最大加到8++flash;elseif(x==0&&y==0&&flash0)//最小减到0--flash;P2=led_table[flash];播放音乐时又有所不同:播放音乐时,led灯要精确地显示当前音符的节拍,所以if语句里加了一条限制语句:flashjiepai)代码:if(out==1&&flash8&&flashjiepai)/*out==1表示有歌曲发声时,(flashjiepai)使led灯刚好指示节拍*/++flash;elseif(out==0&&flash0)--flash;P2=led_table[flash];这样做,就能看得出音符的节拍了。只是,由于led灯的个数有限,所以大于二分音符(2拍)的节拍就无法看到了。因为8个灯全亮才表示二分音符。如果当初采用16个灯的话,就没有这个窘境了。【蜂鸣器】:蜂鸣器采用一个s8550NPN三极管驱动,一个可变电阻改变音量。三极管的选用要注意放大倍数,放大倍数太小会导致蜂鸣器声音很小。最初采用8050就造成了这个问题。另外,采用P3.0口连接接蜂鸣器是一个错误。因为P3.0、P3.1是烧写程序用到的接口。倘若连接了其他器件,每次调试都要拔下烧写线,很不方便。【音乐相关知识】:【表6.5.1】音符频率对照表音符频率(HZ)简谱码(T值)音符频率(HZ)简谱码(T值)低1DO262636280xf88c#4FA#74064860#1DO#27763731中5SO784648980xfd82低2RE294638350xf95b#5SO#83164934#2RE#31163928中6LA880649680xfdc8低3M330640210xfa15#693264994低4FA349641030xfa67中7SI988650300xfe06#4FA#37064185高1DO1046650580xfe22低5SO392642600xfb04#1DO#110965085#5SO#41564331高2RE1175651100xfe56低6LA440644000xfb90#2RE#124565134#646664463高3M1318651570xfe85低7SI494645240xfc0c高4FA1397651780xfe9a中1DO523645800xfc44#4FA#148065198#1DO#55464633高5SO1568652170xfec1中2RE587646840xfcac#5SO#166165235#2RE#62264732高6LA1760652520xfee4中3M659647770xfd09#6186565268中4FA698648200xfd34高7SI1967652830xff038音调、节拍以及编码的确定方法:一般说来,单片机演奏音乐基本都是单音频率,它不包含相应幅度的谐波频率,也就是说不能像电子琴那样能奏出多种音色的声音。因此单片机奏乐只需弄清楚两个概念即可,也就是“音调”和节拍。其中节拍表示一个音符唱多长的时间。音调的确定:不同音高的乐音是用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的音叫自