利用单片机(或单板机)奏乐大概是无线电爱好者感兴趣的问题之一。本文从单片机的基本发间实验出发,谈谈音乐程序的设计原理,并给出具体实例,以供参考。下面提供2个列子,大家根据 需要自行选择
单片机最小系统,两位LED由串口输出接两个164驱动,Lout,Rout为左右声道输出,SET, ALT0, ALT1为三个按键,也可自己在开始的I/O定义改成你想用的I/O口;12M晶振若用89C51则只可装下约14首歌曲,用89C52则可装下近40曲
源程序; Electronic Music; Version 4.50; Copyright (c) XAJ 2001;============================LOUT BIT P1.0 ;左声道输出ROUT BIT P1.2 ;右声道输出SET BIT P3.3 ;SET按键ALT0 BIT P3.6 ;ALT0按键ALT1 BIT P3.7 ;ALT1按键
;REPNUM EQU 09H重复段编号STATU EQU 0AH;状态寄存器LDR EQU 0BH;左低音度数RDYDSR EQU 0CH;右低音度数LDYAR EQU 0DH;左低音协助RDYAR EQU 0EH;右低音协助JPCLK EQU 0FH;节拍时钟GENCLK EQU 10H;通用时钟SNSDCLK EQU 11H;搜、存显示时钟GEN16T0 EQU 12H;通用16位时钟GEN16T1 EQU 13H; SETST0 EQU 14H;设置状态SETST1 EQU 15H; 定时时钟DISNUM0 EQU 16H;显示数值DISNUM1 EQU 17H;寄存器(2位)CSN EQU 18H;当前曲曲号REP0L EQU 19H;0号重复段地址REP0H EQU 1AH;REP1L EQU 1BH;1号重复段地址REP1H EQU 1CH;REP2L EQU 1DH;2号重复段地址REP2H EQU 1EHREP3L EQU 1FH;3号重复段地址REP3H EQU 23H;COSPEEDN EQU 24H;SR EQU 25H;
LOCF BIT 00H;左声道开关标志ROCF BIT 01H;右声道开关标志SECHSTOF BIT 02H;搜索、存储标志SF BIT 03H;下一曲标志CSOF BIT 04H;当前曲锁存/释放CUYFD BIT 05H;当前音符显示KSETF BIT 06H;SET键按下标志KALT0F BIT 07H;ALT0键按下标志KALT1F BIT 08H;ALT1键按下标志SPEEDF BIT 09H;速度增/减标志TONEF BIT 0AH;音调增/减标志YPBIT BIT 0BH;音频逻辑输出KBDISF BIT 0CH;键盘显示标志REP0F BIT 0DH;0号重复段控制REP1F BIT 0EH;1号重复段控制REP2F BIT 0FH;2号重复段控制REP3F BIT 10H;3号重复段控制
SBOTM EQU 25H;堆栈区(栈底)BUFF0 EQU 43H;锁存曲数BUFF EQU 44H;锁存曲缓冲区;============================
;=========BEGIN==============ORG 0000HLJMP MAIN;---------T0INT--------------ORG 000BHLJMP T0INT
;---------T1INT--------------ORG 001BHLJMP T1INT;1.音频发生器;---------YPFSQ(01)----------ORG 0030HT0INT: MOV TL0,R4MOV TH0,R5PUSH PSWPUSH ACCPUSH 01HJB LOCF,ROPERMOV R1,#00HMOV A,LDYART0LLOP: RRC AMOV YPBIT,CXCH A,R1CJNE A,LDYDSR,T0LNEXTMOV C,YPBITMOV LOUT,CINC LDYAR; INC P0 SJMP ROPERT0LNEXT: XCH A,R1INC R1SJMP T0LLOPROPER: JB ROCF,T0RETIMOV R1,#00HMOV A,RDYART0RLOP: RRC AMOV YPBIT,CXCH A,R1CJNE A,RDYDSR,T0RNEXTMOV C,YPBITMOV ROUT,CINC RDYAR; INC P2SJMP T0RETIT0RNEXT: XCH A,R1INC R1SJMP T0RLOPT0RETI: POP 01HPOP ACCPOP PSWRETI;2.通用时钟;---------CLOCK(02)----------T1INT: MOV ,#0F0HMOV TH1,#0D8HPUSH PSWPUSH ACCINC JPCLKINC GENCLKINC SNSDCLKMOV A,SNSDCLKCJNE A,#0FFH,T1NEXTCLR SECHSTOFT1NEXT: INC GEN16T0MOV A,GEN16T0CJNE A,#100,T1NEXT0MOV GEN16T0,#00HINC GEN16T1T1NEXT0: INC SETST0MOV A,SETST0CJNE A,#100,T1RETIMOV SETST0,#00HINC SETST1MOV A,SETST1CJNE A,#20,T1RETIMOV SETST1,#00HMOV STATU,#00HT1RETI: POP ACCPOP PSWRETI;3.显示子程序;---------DISPLAY(03)--------DISPLAY: PUSH ACCPUSH DPLPUSH DPHMOV D,#T_FIGCODEMOV A,DISNUM0MOVC A,@A DPTRMOV SBUF,AJNB TI,$CLR TIMOV A,DISNUM1MOVC A,@A DPTRMOV SBUF,AJNB TI,$CLR TIPOP DPHPOP DPLPOP ACCRETT_FIGCODE:DB 088H,0EBH,04CH,049H; 0 1 2 3DB 02BH,019H,018H,0CBH; 4 5 6 7DB 008H,009H,00AH,038H; 8 9 A BDB 09CH,068H,01CH,01EH; C D E FDB 080H,0E3H,044H,041H; 0. 1. 2. 3.DB 023H,011H,010H,0C3H; 4. 5. 6. 7.DB 000H,001H,002H,030H; 8. 9. A. B.DB 094H,060H,014H,016H; C. D. E. F.DB 0FFH,02FH,098H,07FH; 熄灭 # G -DB 07CH,078H,0BCH,00AH; c o L RDB 029H; Y;4.主程序MAIN;---------MAIN(04)-----------MAIN: MOV R0,#01HCLR ACLRAM: MOV @R0,AINC R0CJNE R0,#80H,CLRAMMOV R0,AMOV SP,#SBOTMMOV 08H,#BUFF;MOV 09H,#BUFFMOV SCON,#00HMOV TMOD,#11HMOV TL1,#0F0HMOV TH1,#0D8HSETB EASETB ET0SETB ET1SETB TR1
START: MOV DPTR,#T_SONGSRYF: LCALL RYFSUPMOV A,R7JZ STARTCJNE R7,#0FFH,SYFJBC NEXTSF,NEXTSCLMOV A,STATUJNZ GONSBQMOV A,BUFF0JNZ QCLLCALL PAQSCLSJMP MQNFDMPSQCL: LCALL PSQSCLMQNFD: LCALL QNFDSUPMOVPJRYF: INC DPTRINC DPTRSJMP RYFNEXTSCL: LCALL ESTOJGJB CSBESTOF,CALLPSCLLCALL PAQSCLSJMP MOVPJRYFCALLPSCL: LCALL PSQSCLSJMP MOVPJRYFGONSBQ: LCALL CSDPTRINC DPTRINC DPTRSJMP MOVPJRYFSYF: CJNE R6,#0FFH,CALLPLAYLCALL REPCLSUPSJMP MOVPJRYFCALLPLAY: LCALL YFDSUPLCALL PLAYSJMP MOVPJRYF;5.读音符子程序;---------RYFSUP(05)--------RYFSUP: CLR AMOVC A,@A DPTRMOV R6,AMOV A,#01HMOVC A,@A DPTRMOV R7,ARET;6.统唱曲首处理;---------PAQSCL(06)--------PAQSCL: MOV CSN,R6INC DPTRINC DPTRLCALL RYFSUPMOV 02H,R6MOV 03H,R7RET;7.存唱曲首处理;---------PSQSCL(07)--------PSQSCL: PUSH PSWSETB RS0CLR RS1PSQC7E: CJNE R0,#7EH,PSQNEXTPSQNEXT: JC PSQNEXT1MOV R0,#BUFFSJMP PSQC7EPSQNEXT1: MOV A,@R0JNZ PSQNEXT2INC R0INC R0INC R0SJMP PSQC7EPSQNEXT2: MOV CSN,@R0INC R0MOV 02H,@R0INC R0MOV 03H,@R0INC R0POP PSWLCALL CSDPTRINC DPTRINC DPTRRET;8.曲号闪显子程序;---------QNFDSUP(08)-------QNFDSUP: PUSH ACCMOV GEN16T0,#00HMOV GEN16T1,#00HQNGON: LCALL CSNSDISNLCALL DISPLAYMOV GENCLK,#00HQNWAIT: MOV A,GENCLKCJNE A,#35,QNWAITMOV DISNUM0,#20HMOV DISNUM1,#20HLCALL DISPLAYMOV GENCLK,#00HQNWAIT1: MOV A,GENCLKCJNE A,#15,QNWAIT1MOV A,GEN16T1CJNE A,#02,QNGONPOP ACCRET;9.曲号送显示寄存器;---------CSNSDISN(09)------CSNSDISN: MOV A,CSNANL A,#0FHLCALL CSBESTOJGJNB CSBESTOF,NADPADD A,#10HNADP: MOV DISNUM0,AMOV A,CSNSWAP AANL A,#0FHMOV DISNUM1,ARET;10.当前曲是否被存储判断;---------CSBESTOJG(10)-----CSBESTOJG:PUSH ACCPUSH PSWMOV A,BUFF0JZ CSTOFMOV R0,#BUFFCSBCMPCSN:MOV A,@R0CJNE A,CSN,CSBGSCANSETB CSBESTOFSJMP CSBRETCSBGSCAN: INC R0INC R0INC R0CJNE R0,#7EH,CSBNEXTCSBNEXT: JC CSBCMPCSNCLRCSTOF: CLR CSBESTOFMOV R0,#BUFFCSBCMP0: MOV A,@R0JZ CSBRETINC R0INC R0INC R0CJNE R0,#7EH,CSBNEXT1CSBNEXT1: JC CSBCMP0CSBRET: POP PSWPOP ACCRET;11.找当前曲首址;---------CSDPTR(11)--------CSDPTR: MOV DPTR,#T_SONGSCSDSCAN: LCALL RYFSUPCJNE R7,#0FFH,CSDNEXTMOV A,R6CJNE A,CSN,CSDNEXTSJMP CSDRETCSDNEXT: INC DPTRINC DPTRSJMP CSDSCANCSDRET: RET;12.重复段处理子程序;---------REPCLSUP(12)------REPCLSUP: MOV A,R7ANL A,#0FHCJNE A,#02H,CMPA3MOV A,R7SWAP AANL A,#0FHJNZ H4CMP1JNB REP0F,REPRET0CLR REP0FMOV DPL,REP0LMOV DPH,REP0HREPRET0: RETH4CMP1: CJNE A,#01H,H4CMP2JNB REP1F,REPRETCLR REP1FMOV DPL,REP1LMOV DPH,REP1HRETH4CMP2: CJNE A,#02H,H4CMP3JNB REP2F,REPRETCLR REP2FMOV DPL,REP2LMOV DPH,REP2HRETH4CMP3: CJNE A,#03H,REPRETJNB REP3F,REPRETCLR REP3FMOV DPL,REP3LMOV DPH,REP3HRETCMPA3: CJNE A,#03H,REPRETMOV A,R7SWAP AANL A,#0FHJNZ H4VS1SETB REP0FMOV REP0L,DPLMOV REP0H,DPHSJMP SREPHADH4VS1: CJNE A,#01H,H4VS2SETB REP1FMOV REP1L,DP