音乐程序--玩具.doc_第1页
音乐程序--玩具.doc_第2页
音乐程序--玩具.doc_第3页
音乐程序--玩具.doc_第4页
音乐程序--玩具.doc_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

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

文档简介

单片机音乐程序来源:作者:时间:2008-04-09发布人:宝贝单片机音乐编程程序实验【字体:大 中 小】来源: 作者:/ 单片机音乐编程实验在很多儿童玩具或一些需要音乐提示(如报警仪、定时闹钟、电子宠物等)的场合,需要用到单片机音乐编程的功能。原理就是利用单片机的引脚发出某一定频率的信号驱动外部发声设备发出声音,或者放出美妙的音乐。在这个例程中,音乐曲调的原始编码已做好,只要按照曲谱给定参数即可实现播放不同的乐曲,使实验生动有趣。参数两个:前一个按照曲谱对照编码表给定,第二个,为节拍数,8-1拍,4-半拍。 musich equ 40h ;音乐定时高位数据 musicl equ 41h ;音乐定时低位数据musicstart equ 42h ;音乐开始首地址; * 预定义结束 *org 00h ;程序开始jmp main ;跳转到主程序org 1bh ;定时器T1中断入口地址jmp timer1 ;定时器服务程序 org 030h ;主程序代码开始 main:mov sp,#30h;设置堆栈lcall music ;调用音乐程序jmp main ;重新开始 musdelay:mov r0,#20 ;短时间延时d:djnz r0,d ;延时时间 20uSret;返回; * 定时器 服务程序 * timer1:clr tr1 ;停止定时器工作mov th1,musich ;重新设置定时初值 mov tl1,musicl ;cpl beep ;从蜂鸣器输出声音 setb tr1 ;开始定时工作 reti ;中断返回;* ;* 音乐播放程序 * music:mov tmod,#10h;设置定时器T1工作方式1 setb ea;总的中断setb et1 ;定时器T1中断允许mov musicstart,#00h;音乐开始地址mov musich,#0ffh ;音乐定时常数高位 mov musicl,#0ffh ;音乐定时常数低位loopm:mov dptr,#mu_tab ;得到音符表头mov a,musicstart ;开始查表 movc a,a+dptr ;获得音乐数据jz musend ;结束符 00H,返回 rl a ;A*2mov b,a;暂存地址mov dptr,#mustab ;获得音符表头movc a,a+dptr ;根据音乐数据查得定时常数mov musich,a ;保存定时常数高位 mov th1,a ;设置定时器高位常数 mov a,b;开始找低位数据 inc a ;指向下一个数据mov dptr,#mustab ;得到音符表头movc a,a+dptr ;查得低位数据 mov musicl,a ;保存数据mov tl1,a ;设置定时低位常数 setb tr1 ;定时器T1开始工作 mov dptr,#mu_tab ;得到音乐表 inc musicstart ;指向下一个单元(音符节拍)mov a,musicstart ;开始查找movc a,a+dptr ;找到数据lcall delay1 ;根据参数延时,发出持续音乐inc musicstart ;指向下一个音 clr tr1;停止发声lcall delay jmp loopm;重复,直到遇到结束符号 00H. musend:clr tr1;乐曲播放完毕,关闭定时器 clr ea ;禁止中断clr et1;关闭定时器T1中断clr beep ;禁止蜂鸣器 mov a,#20 lcall delay1ret ;* ;* 节拍发生器 ,产生音乐节拍 * delay1:mov r0,#00h;节拍发生器,用来发生节拍mov r1,#00h;mov r2,a ;这是节拍发生器的参数,当它为8dlay1:djnz r0,dlay1 ;表示1拍 mov r0,#00h djnz r1,dlay1mov r0,#00h mov r1,#00hdjnz r2,dlay1ret ; ; * 延时 产生休止符 * delay:mov r0,#00h;延时 10msmov r1,#100 dlay:djnz r0,dlay mov r0,#100 djnz r1,dlay ret; *; *曲谱编码,这是定义的曲谱表,对应如下 *; 1 低音 DO 2 低音 RE 3 低音ME 4 低音 FA 5 低音 SO 6 低音LA 7 低音SImustab: db h,j, 0f8h,8bh, 0f9h,5bh, 0fah,14h, 0fah,0ch, 0fbh,03h, 0fbh,8fh, 0fch,0bh; 8 中音 DO 9 中音 RE 0ah 中音ME 0bh 中音 FA 0ch 中音 SO 0dh 中音LA 0eh 中音SIdb 0fch,43h, 0fch,0abh, 0fdh,08h, 0fdh,33h, 0fdh,81h, 0fdh,0c7h, 0feh,05h ; 0fh 高音 DO 10h 高音 RE 11h 高音ME 12h 高音 FA 13h 高音 SO 14h 高音LA 15h 高音SI db 0feh,21h, 0feh,55h, 0feh,84h, 0fdh,99h, 0feh,0c0h, 0feh,0e3h, 0ffh,02h;以下为音乐乐谱代码,前两位表示曲谱,后一位表示节拍 ;8为 1 拍,4 -半拍 mu_tab: db 6,4,8,4,10,4,1,4, 9,8,8,4,7,4,10,8,9,8,6,16db 8,4,10,4,12,4,12,4, 13,8,12,4,11,4,10,16db 00hend ;c语言;*/ 音乐编程/通过蜂鸣器发出讯响/只要通过修改 后面的音乐程序里面的码/表就可以自己谱曲唱歌!/前一个参数为按照编码表给定,第二个参数为节拍数#include #define uchar unsigned char#define key1 P3_4 /键盘定义#define key2 P3_5#define key3 P3_6#define beep P3_7 /蜂鸣器定义uchar timer_h;uchar timer_l;/*void reset(); void delay(uchar times);void dems(); /休止符延时void display(uchar disseg,uchar disdata);uchar keyb();/ 这里定义的是数码管对应的字符字根code uchar disbuf_u=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78, 0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e;/ 这里定义音乐音符表code uchar musictabl=0xf0,0xf0, 0xf8,0x8b,0xf9,0x5b,0xfa,0x14,0xfa,0x0c,0xfb,0x03,0xfb,0x8f,0xfc,0x0b, 0xfc,0x43,0xfc,0xab,0xfd,0x08,0xfd,0x33,0xfd,0x81,0xfd,0xc7,0xfe,0x05, 0xfe,0x32,0xfe,0x55,0xfe,0x84,0xfe,0x99,0xfe,0xc0,0xfe,0xe3,0xff,0x02;/这里定义音乐曲谱表格code uchar musicdata=6,4, 8,4,10,4, 1,4, 9,8, 8,4, 7,4,10,8,9,8,6,16, 8,4,10,4,12,4,12,4,13,8,12,4,11,4,10,16,0;/ *void ClockIrqHandler (void) interrupt 1 using 3; /定义定时器T0中断服务程序/下面是定时器T0的中断服务程序void ClockIrqHandler (void) interrupt 1 using 3 TR0 = 0; /关闭定时器 TL0 = timer_l; TH0 = timer_h; beep = beep; TR0 = 1; /打开定时器/ * 定时器程序 *uchar keybuf;void main() uchar counts,mustmp,tmp,keym = 0; /键盘返回结果的缓冲区 reset(); /调用初始化程序 while(1) /设置一个无限制循环 for(counts=0;musicdatacounts!=0;counts+=2) mustmp = musicdatacounts; TR0 = 0; tmp = musictablmustmp; timer_h = tmp; tmp = musictablmustmp+1; timer_l = tmp; TR0 = 1; display(0,musicdatacounts+1); delay(musicdatacounts+1); TR0 = 0; dems(); / display(250,0); / delay(255); / delay(255); / display(keybuf-1,keybuf); /在相应的位置显示返回的结果 void reset() keybuf = 0; P1 = 255; /关闭LED显示 P0 = 0; /关闭数码显示 P2 = 255; /* 上面是一些基础定义 * TL0 = 0xff; /初值 TH0 = 0xff; /初值 ET0=1; / 允许定时器T0中断 EA =1; / 中断总允许/*/下面是延时程序。具体的延时时间不能通过表面程序看出,(为什么?)/如果我们需要一个精密的延时程序,那么我们可以采用内嵌汇编代码的方式void delay(uchar times) int t=24000; /延时倍数 uchar i=times; for(;i!=0;i-) for(;t!=0;t-)void dems() /休止符延时_asm mov R0,#0 llp: mov R1,#100 llk: djnz R1,llk djnz R0,llp_endasm; /这里是显示子程序,入口参数为/ disseg - 位选 可选范围 0-7 一共8个数码管/ disdata - 段选 可选范围 0-31 一个32个字符/ 段选 0-15 16个字符 为 0-F/ 段选 16-31 16个字符 为 0.-F.void display(uchar disseg,uchar disdata) uchar dataf; if(disseg 8) /只有当要显示的位数有效,才显示.否则,不显示 dataf = 1; while(disseg) dataf = 1; disseg-; P0 = dataf; P2 = disbuf_udisdata; elseP0=0,P2=255; /关闭数码管显示uchar keyb() uchar key,keytmp; key1 = 1; /将输出线拉高 key2 = 1; key3 = 1; key = P3 ; /读回来 key = key & 0xf0; /获得键盘结果 if(key = 112 ) return 0; /如果用户没有按键返回 0 else keytmp = key; delay(1); /判断是不是干扰 key = P3 & 0xf0; if (key != keytmp ) return 0; /是干扰,

温馨提示

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

评论

0/150

提交评论