《北邮单片机实验报告简易电子琴.doc》由会员分享,可在线阅读,更多相关《北邮单片机实验报告简易电子琴.doc(38页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、2014年小学期单片机设计实验报告题目:基于单片机的电子音乐发生器班 级:班序号:实验组号:学生:指导教师:基于单片机的电子音乐发生器实验摘要此次本组制作的基于PIC单片机的电子音乐发生器是具有LCD显示屏提示的音乐简单演奏、播放、存储等功能的演示作品,拥有以下4种功能:1按键演奏:即“电子琴”功能,可以用键盘上的“1”到“A”键演奏从低音sol到高音do等11个音;2点歌功能:即按动“B”“C”键分别演奏两首乐曲(可以表现准确的音高和音长)。3.存储音乐功能:即按右下角“F存储”键,然后按键演奏并存储,随后按“E”键结束,之后按“D键”就可以播放存储的乐曲了;4.液晶显示功能:即在开始时显示
2、“hello!”,在点播时分别显示“song b”、“song c”,在存储时显示“saving”。电子音乐发生器采用以Microchip公司的PIC16F877芯片为核心的简单控制系统,外部电路连接有喇叭、键盘、LCD液晶显示屏以与其他必要系统调节元件。软件设计中涉与PORTBPORTCPORTDPORTE用作普通数字I/O脚功能。本实验用单片机PORTBD接收来自键盘输入的指令信息,由此确定LCD液晶屏幕显示以与喇叭播放容,再通过PORTCDE输出声音或字幕信息。关键字单片机microcontroller 芯片CMOS chip 音乐发生器music generator 分频fractio
3、nal frequency一、实验论证与比较本设计的核心器件是单片机芯片和音频功放芯片。单片机采用以Microchip公司的PIC16F87X系列中的PIC16F877芯片为核心构建简单控制系统,它完全可以满足本设计功能的需要。此音乐发生器设计利用单片机的输入输出功能,当按下播放功能键时,单片机的输出功能使外部电路连接的喇叭和LCD液晶显示屏同时播放声音与显示文字,从而实现各种复杂音乐播放器的功能。在嵌入式系统设计中,扬声器等是常用的输出设备,它具有使用方便、价格便宜、电路接口简单等优点,因此,在嵌入式系统中被广泛使用。同时随着单片机的发展,其功能越来越强大,技术也越来越成熟,由此生产的音乐播
4、放器越来越受到人们的喜爱。因此,在技术性操作、社会因素和经济方面都具有良好的可行性。我在实验中负责了全部软件设计,代码的编写,电路图的设计,以与部分硬件焊接。其中,困难的部分在于,理论上认为电子音乐发生器模拟真正乐器的仿真实现方法,与现实电路实现起来有着一定的差别,在长音、乐谱存储播放上,以与存储功能的代码编写都有一定的难度。二、系统总体设计1、系统模块总体框图2、系统整体流程图3、发音原理播放一段音乐需要的是两个元素,一个是音调,另一个是音符。首先要了解对应的音调,音调主要由声音的频率决定,同时也与声音强度有关。对一定强度的纯音,音调随频率的升降而升降;对一定频率的纯音、低频纯音的音调随声强
5、增加而下降,高频纯音的音调却随强度增加而上升。另外,音符的频率有所不同。基于上面的容,这样就对发音的原理有了一些初步的了解。将相应音高的分频值存储在寄存器里,并将其与对应的按键进行关联,通过键盘扫描子程序将对应的分频值送入单音播放子程序即可产生相应频率的电压方波,再将其输出到喇叭即可产生对应的音高实现电子琴功能。将音符按音高和音长直接存储在数据存储器里并与按键相关联,调用自动演奏子程序产生相应频率和时长的方波电压输出到喇叭即可。三、硬件连接1、键盘和单片机的连接选择用4*4行列式键盘完成输入。4*4行列式键盘又称为矩阵键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。在行线和列
6、线的每一个交叉点上,设置一个按键。这样键盘中按键的个数是44个。这种行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。引脚号所连接的单片机的管脚引脚号所连接的单片机的管脚1RD45RB02RD56RB13RD67RB24RD78RB32、LCD和单片机的连接采用型号为RT1602C的液晶显示屏,液晶显示屏的显示功能强大,可显示大量文字、图形,显示多样,清晰可见, 与传统的阴极射线管相比,液晶显示屏具有占用空间小、低功耗、低辐射、无闪烁、降低视觉疲劳等优点。字符型液晶屏是一种用5*7点阵图形来显示字符的液晶显示器,根据显示的容量可以分为1行16个字、2行16个字、2行20个字等,最常用的
7、为2行16个字。型号为RT1602C的液晶显示屏就是2行16个字。它有16个管脚,分别有电源地、电源正、偏压信号、读写控制、使能控制、I/O接口、背光控制等功能。它的读写操作、屏幕和光标的操作都是通过指令编程来实现的。脚号符号管脚功能与接发脚号符号管脚功能与接发1VSS电源地9DB2数据I/O RD22VDD电源正10DB3数据I/O RD33VO对比调整电压11DB4数据I/O RD44RS数据/命令控制 RE012DB5数据I/O RD55R/W读/写控制13DB6数据I/O RD66E使能信号 RE114DB7数据I/O RD77DBO数据I/O RD015BLA背光源正8DBI数据I/
8、O RD116BLK背光源负3、扬声器和单片机的连接扬声器的连接方法较前面的容易很多。起初是将喇叭的正极直接连接在RE0上,负极接地,但我们发现这样发出的声音很小,音色也不好,于是在喇叭和单片机之间增加了一E个功率放大模块,这样声音就放大、稳定了很多。四、调试过程1、软件程序部分我们首先在大体上对音乐播放器的功能按几个部分进行了划分,其中包括键盘扫描、单键演奏、键盘点播乐曲、音乐输入存储与播放、液晶显示等几个部分。 1)、音乐的存储和演奏:起初我们设想把音乐的声调高低这些信息用不同的电压代表。通过AD转换存储到存单元里,而这不同的电压正可以通过不同的按键实现,后来在具体编程时发现有困难,于是在
9、网上查到相应音高的分频值存储在寄存器里,并将其与对应的按键进行关联,通过键盘扫描子程序将对应的分频值送入单音播放子程序即可产生相应频率的电压方波,再将其输出到喇叭即可产生对应的音高实现电子琴功能。将音符按音高和音长直接存储在数据存储器里并与按键相关联,调用自动演奏子程序产生相应频率和时长的方波电压输出到喇叭即可。2)、液晶显示:应用了查表功能按四位16进制显示在液晶屏上。3)、键盘扫描:键盘扫描子程序是根据实验板的布线,先让行输出高电平,列为低电平,如有键按下则此键所在行也变成低电平,由此取得行码;同理取得列码,将两个码首尾相接取得键位码,并且事先将据此设计好的键位码存在寄存器里,通过地址指针
10、不断将取得的键位码与预置的键位码比较从而确定出哪个键被按下了。4)、音乐存储与播放部分:用F键将标志位置1后进入存储状态,将按下的键逐一存到一串连续的地址中去,可是fsr指针只有一个,键盘扫描时用到了,所以在存储时只好在每次存储前重新对fsr赋值。自动播放子程序因为知道了音长是按几分音符来控制的,而且都是倍数关系,于是我又加了一个计数器用来控制音长。(1)存储功能流程图(2)单音独奏功能流程图(3)重放功能流程图2、硬件部分硬件部分的完成分为:电路图的设计、实验板的焊接、实际电路的整体连接三部分。在实验开始前的开题报告中,我组还准备加入蓝牙模块,可以通过手机控制音乐的播放。因为知道PIC16F
11、877单片机有USART端口(RC6,RC7),可以进行串行通信,只需借助有USART端口的蓝牙模块,就可以通过蓝牙模块来与蓝牙设备进行通信,这样就可以手机来控制单片机来产生调用相应的程序来产生一定频率的声音,并且PIC16F877的串行通信模块,在接收缓冲寄存器满时,在中断使能的情况下可以产生中断,这样就可以跳入中断子程序,从而就能够实时控制单片机,来实时弹奏音乐。所以蓝牙电子琴是可行的。在前面的过程基本完成并测试稳定后,我们开始了对蓝牙模块的研究,研究过程并不顺利,首先在器材上我们的购买的蓝牙芯片只有连接凹槽,没有连接管脚,这一时让我们犯了难。后来通过向老师求助,拿到了一个可以引出插孔的小
12、电路板,但是焊接有一些困难。原本老师想要帮助我们,我们最后还是决定自己完成,通过多次练习和谨慎的焊接之后,我们终于成功的自己焊接上了。后面面临的困难却没有这么容易克服了,不但编程烧入后LED灯的点亮情况一直不正确,也不能用手机搜索到该蓝牙设备,在反复调试失败和验收时间迫近的情况下,我们不得不选择放弃使用蓝牙模块。这是我们这次实验的一个遗憾。五、参考文献PIC单片机实用教程基础篇 (五号 宋体)学海航空航天大学使用说明:的确是一本不可或缺的教材,本书列举了很多实用的具有实战意义的例子,单片机入门就是通过把这本书里的好例子一字一行敲进电脑去来实现的。PIC单片机实用教程提高篇学海航空航天大学使用说
13、明:继承了前面基础篇的风格,例子也具有实战意义,主要讲RA、TMR2的使用和CCP模块的PWM脉宽调制功能。六、实验心得体会小学期的第一周基本上是泡在实验室,一日三餐基本上是在实验室解决的。在这一周里,一直在看书,也就是在这一周里看了快两本有关PIC单片机相关的资料书。感觉相当的充实,同时也学到了很多东西,几乎是从零开始,一点点地学习汇编语言,一点点地学学PIC16F877的知识,到现在每一个管脚都还在脑海中。硬件也是自己动手,从电路的设计到电路的焊接。 现在来看这个小学期学到了许多东西。刚开始是感觉挺难的,通过耐心的学习,我从不甚了解到编出自己的程序,到调试成功,真的是学到了很多。开始时心里
14、一点底也没有,直到键盘扫描和单键演奏程序编出来后才逐渐有了信心,当我们按下键盘喇叭第一次发出音阶时,我真是激动极了,那种成就感真的是难以言表。虽然实验过程中遇到很多困难比如自动播放子程序开始编的程序在演奏时只表现音高而没有表现音长,所以放出来的乐曲效果很差,还有存储代码想了好久,但是我都通过自己思考以与查阅资料或询问老师将问题解决了,我不仅了解到了自学的乐趣和重要性,同时也锻炼了实验中的动手能力,了解了汇编语言,更重要的是这次合作式的小学期也让我体会出团队的团结、相互的默契和彼此的信任在团队(尽管这个团队也许只有两三个人)的协作中是多么重要,同时也为我们步入社会、参加工作提供了一次很好的“演练
15、”机会。 虽然已经完成了本次小学期的任务,但最后的结果相较于最初的预期还是有一定的差距,这是自身能力尚且不足的体现。其实在学校要学的不仅是书本上的东西,更重要的是自学的能力、独立思考的能力和动手的能力。要想在竞争异常激烈的现代社会立足,就必须有实力。在学校的时间是最好的学习机会,一定要珍惜好这有限的时间,多学知识,尽量充实自己,为以后进入社会多做准备。附代码:;*变量定义区*indfequ00htmr0 equ 01h pclequ02hstatusequ03hc equ 0 zequ2rp0equ5rp1equ6fsrequ04hfsr2equ05hportbequ06htrisbequ86
16、hportcequ07htriscequ87hportdequ08htrisdequ88hporte equ 09h trise equ 89h pclathequ0ahintcon equ 0bh t0if equ 2 t0ie equ 5 pir1equ0ch;定义第一中断标志寄存器pie1equ8ch;定义第一中断使能寄存器tmr1lequ0eh;定义定时器1低位寄存器地址tmr1hequ0fh;定义定时器1高位寄存器地址t1conequ10h;定义tmr1控制寄存器rcstaequ18htxstaequ98htxregequ19hspbrgequ99hrcregequ1ahgieequ
17、7peieequ6rcifequ5rcieequ5txifequ4option_regequ81hrbpuequ7delMequ20h;定义两个延时变量寄存器delNequ21hdelKequ0ffh;定义一个层循环延时常数valueequ22h;暂存按键列码和位置码w_temp equ 23h ;定义备份w的地址 countequ 24h;定义循环次数寄存器地址portc_pequ 25h;定义缓冲端口c的数据寄存器地址rdelay equ 26h;定义音乐延时寄存器地址flag1equ 27h;定义复选标志寄存器的地址flag2equ28h;定义二次复选寄存器的地址count2equ29h
18、indf2equ2ahtmp1equ2fh ;定义临时寄存器地址tmr1lbequ30htmr1hbequ31hadcon1equ9fhdoequ50h;定义音符reequ51hmiequ52hfaequ53hsolequ54hlaequ55hsiequ56hHdoequ57hLsolequ58hLlaequ59hLsiequ5ahHreequ5bhHmiequ5chHfaequ5dhp1lequ60h ;定义拍节寄存器地址p1hequ 61hp2lequ62hp2hequ63hp3lequ64hp3hequ65hp4lequ 66hp4hequ67hp05lequ 68hp05hequ 69
19、hp15lequ6ahp15hequ 6bhp025lequ6chp025hequ 6dhp075lequ6ehp075hequ 6fh;*数据寄存器写入welcome*resetorg0000h nopcalllcdinitmovlw77h;wbsfporte,0calllcdsendmovlw65h;ecalllcdsendmovlw6ch;lcalllcdsendmovlw63h;ccalllcdsendmovlw6fh;ocalllcdsendmovlw6dh;mcalllcdsend movlw65h;ecalllcdsendmovlwb10100000 calllcdsendmov
20、lwb01110100calllcdsendmovlwb01101111calllcdsendmovlwb10100000calllcdsendmovlwb01110101;usecalllcdsendmovlwb01110011calllcdsendmovlwb01100101calllcdsendbcf porte,0;nextrowmovlwb11000000calllcdsendmovlwb00000001movwfportemovlw b01000010 call lcdsendmovlwb01000011calllcdsendmovlwb00111010calllcdsendmov
21、lw53h;sbsfporte,0calllcdsendmovlw4fh;ocalllcdsendmovlw4eh;ncalllcdsendmovlw47h;gcalllcdsend movlw b01000110 call lcdsend movlw73h;sbsfporte,0calllcdsendmovlw61h;acalllcdsendmovlw76h;vcalllcdsendmovlw65h;ecalllcdsend;*主程序*mainbsfstatus,5 ;设置文件寄存器的体1 movlw 00h ;将端口c的方向控制码00h先送w movwf trisc ;再转到方向寄存器,将
22、其设为输出movlw 07hmovwf adcon1movlw 00hmovwf trise movlw 0ffh ;同理,将端口b设置为输入 movwf trisb ; movlw 0ffh ;将端口d设置为输入 movwf trisd ;bsfpie1,0;开放tmr1中断使能位 bcf status,5 ;恢复文件寄存器的体0movlw34h;设置控制寄存器容:暂时不打开tmr1movwft1con;预分频器设为“1:8“clrfportcgotohz;*音高分频值对应表*hzmovlwd100 movwfdomovlwd117movwfremovlwd132movwfmimovlwd1
23、39movwffamovlwd152movwfsolmovlwd163movwflamovlwd173movwfsimovlwd178movwfHdomovlwd48movwfLsolmovlwd70movwfLlamovlwd91movwfLsi;*音符延时对应表*movlw85h;1p分频初始值movwfp1hmovlw0eehmovwfp1lmovlw00bhmovwfp2hmovlw0dchmovwfp2lmovlw0c2hmovwfp05hmovlw0f7hmovwfp05lmovlw48hmovwfp15hmovlw0e5hmovwfp15lmovlw0e1hmovwfp025hm
24、ovlw7bhmovwfp025lmovlw0a4hmovwfp075hmovlw72hmovwfp075l;*在ram中建立键位码表* movlw 77h ;1 movwf 40h ; movlw 7bh ;2 movwf 41h ; movlw 7dh ;3 movwf 42h ; movlw 7eh ;4 movwf 43h ; movlw 0b7h ;5 movwf 44h ; movlw 0bbh ;6 movwf 45h ; movlw 0bdh ;7 movwf 46h ; movlw 0beh ;8 movwf 47h ; movlw 0d7h ;9 movwf 48h ; m
25、ovlw 0dbh ;0 movwf 49h ; movlw 0ddh ;a movwf 4ah ; movlw 0deh ;b movwf 4bh ; movlw 0e7h ;c movwf 4ch ; movlw 0ebh ;d movwf 4dh ; movlw 0edh ;e movwf 4eh ; movlw 0eeh ;f movwf 4fh ;checkbcfflag2,0 call kbscan ;调用键盘扫描子程序comfvalue,0;位置码取反送wbtfscstatus,2;测试有键按否?有!跳过下条指令gotocheck;无!则循环检测movlw.13;预置外循环变量m
26、ovwfdelM;以便产生10ms延时calldelay;调用延时子程序消除抖动call kbscan;再次调用键盘扫描子程序btfscstatus,2;测试有键按否?有!跳过下条指令gotocheck;无!则循环检测gototrans;调用键值翻译子程序gotocheck;*键盘扫描和按键识别子程序*kbscan bsf status,5 ;设置文件寄存器的体1 bcf status,6 ; bcfoption_reg,rbpu movlw0fh;rb的低四位列信号为输入movwftrisbmovlw0fh;rd的高四位行信号为输出movwftrisdbcfstatus,rp0movlw00
27、h;4条行线全部输出0movwfportdnopmovfportb,0andlw0fhmovwfvalue;得到的列码暂存到VALUE寄存器中xorlw0fhbtfscstatus,z;列码不是全部为1则有键按下gotonokeybsfstatus,rp0movlw0f0hmovwftrisb;改变低四位为输出movlw0f0hmovwftrisd;改变高四位为输入bcfstatus,rp0movlw00hmovwfportbnopmovfportd,0andlw0f0hiorwfvalue,1;将行码和列码首尾相连送入valuereturnnokeymovlw0ffhmovwfvaluere
28、turn;*键值翻译子程序*transmovlw40hmovwffsrloopt1movf0,0xorwfvalue,0;与位置码比较btfscstatus,z;不相等则跳一步gotoloopt2incffsr,1;地址指针FSR递增btfssfsr,4;够16次则跳一步gotoloopt1gotocheckreturnloopt2bcffsr,6;等效于fsr-40hmovffsr,0;将fsr存进w寄存器xorlw00h;比较fsr与预存键值,是否相等btfscstatus,2;gotokey1;是,进入按键1子程序movffsr,0;否,恢复w到fsr值,继续向下查询xorlw01hbt
29、fscstatus,2gotokey2movffsr,0xorlw02hbtfscstatus,2gotokey3movffsr,0xorlw03hbtfscstatus,2gotokey4movffsr,0xorlw04hbtfscstatus,2gotokey5movffsr,0xorlw05hbtfscstatus,2gotokey6movffsr,0xorlw06hbtfscstatus,2gotokey7movffsr,0xorlw07hbtfscstatus,2gotokey8movffsr,0xorlw08hbtfscstatus,2gotokey9movffsr,0xorlw0
30、9hbtfscstatus,2gotokey0movffsr,0xorlw00ahbtfscstatus,2gotokeyamovffsr,0xorlw00bhbtfscstatus,2gotokeybmovffsr,0xorlw00chbtfscstatus,2gotokeycmovffsr,0xorlw00dhbtfscstatus,2gotokeydmovffsr,0xorlw00ehbtfscstatus,2gotokeyemovffsr,0xorlw00fhbtfscstatus,2gotokeyfkey1movlw 01hmovwfportc_pmovlwd100gototonek
31、ey2movlw 02hmovwfportc_pmovlwd117gototonekey3movlw 04hmovwfportc_pmovlwd132gototonekey4movlw 08hmovwfportc_pmovlwd139gototonekey5movlw 10hmovwfportc_pmovlwd152gototonekey6movlw 20hmovwfportc_pmovlwd163gototonekey7movlw 40hmovwfportc_pmovlwd173gototonekey8movlw 80hmovwfportc_pmovlwd178gototonekey9mov
32、lw 03hmovwfportc_pmovlwd48gototonekey0movlw 06hmovwfportc_pmovlwd70gototonekeyamovlw 0chmovwfportc_pmovlwd91gototonekeybmovlw 18hmovwfportc_pcallsong_bgotomusic1keycmovlw 30hmovwfportc_pcallsong_c gotomusic2keydmovlw 60hmovwfportc_pbsfflag2,0movlw70hmovwffsrcallreplaykeyemovlw 90hmovwfportc_pbcfflag1,0gotocheckkeyfcallsavemovlw 7fhmovwfportc_pmovlw 0movwfcount2bsfflag1,0callkeepgotocheck;*单键发音子程序*tone movwf w_temp ;备份当前w值bsfstatus,5 bcf status,6 ;设置文件寄存器的体1movlw0;将端口c的方向控制码00h先送wmovwf trisc;将rc设为输出 movlw 0 ;将端口e的方向控制码00h先送w movwf trise ;在转到方向寄存器,