|
6=440Hz,#6=440*1.059463=466.2Hz,7=440*1.059463*1.059463=493.9Hz #5=440÷1.059463=415.3Hz 5=440÷1.059463÷1.059463=392Hz 相邻半音阶的关系为1.059463倍,只要知道"A"=440Hz,即可算出其余半音阶的频率,比A高的用"*",比A低的用"÷" 1.059463=12√2(即2开12次根) 440Hz为钢琴中央C组的A(即"6"音) ok 这是本人一个产品中的音乐单元,很完整,供爱好者参考.
ORG 0000H AJMP CSH 主程序进入点 ORG 000BH LJMP TIM0 定时中断T0入口 ; ;********** ;* 初始化 * ;********** ; ORG 0020H CSH: MOV R0,#7FH 内部RAM(00H~7FH)清零 CSH1: MOV @R0,#00H DJNZ R0,CSH1 MOV SP,#60H 堆栈60H~7FH,【使用89C51】 MOV TMOD,#01H TMOD=11H,T0作16位计数器(4M晶振) CLR TCON.4 T0禁止动作 SETB IE.1 T0允许中断 SETB PT0 T0中断优先 SETB IE.7 系统允许中断 ; ;********** ;* 主程序 * ;********** ; MAIN: MOV 5CH,#00 取简码谱指针 LCALL MUSIC MOV 5CH,#49 取简码谱指针 LCALL MUSIC MOV 5CH,#66 取简码谱指针 LCALL MUSIC MOV 5CH,#100 取简码谱指针 LCALL MUSIC MOV 5CH,#108 取简码谱指针 LCALL MUSIC MOV 5CH,#136 取简码谱指针 LCALL MUSIC MOV 5CH,#174 取简码谱指针 LCALL MUSIC AJMP MAIN ; ;************************* ;* 音乐子程序 MUSIC * ;* 入口: 5CH←简码谱指针 * ;************************* ; MUSIC: MOV A,5CH 简码谱指针装入A MOV DPTR,#TABLE 至TABLE取简码 MOVC A,@A+DPTR MOV R2,A 取到的简码暂存于R2 JZ END1 是否取到00(结束码)? ANL A,#0FH 不是,则取低四位(节拍码) MOV R6,A 将节拍码存入R6 MOV A,R2 将取到的简码再装入R2 SWAP A 高低四位交换 ANL A,#0FH 取低四位(音符码) JNZ SING 取到的音符码是否为0? CLR TR0 是,则不发音 AJMP D1 跳到D1 ; SING: DEC A 取到的音符码减1 MOV 4BH,A 存入(4BH) RL A 乘2 MOV DPTR,#TABLE1 至TABLE1取相对的高字节计数值 MOVC A,@A+DPTR MOV TH0,A 取到的高字节存入TH0 MOV 4AH,A 取到的高字节存入(4AH) MOV A,4BH 再装入取到的音符码 RL A 乘2 INC A 加1 MOVC A,@A+DPTR 至TABLE1取相对的低位 MOV TL0,A 取到的低字节存入TL0 MOV 49H,A 取到的低字节存入(49H) SETB TR0 启动TIMER0 D1: CALL DELAY 基本单位时间1/4拍187毫秒 INC 5CH 取简码谱指针加1 AJMP MUSIC 取下一个码 DD1: RET ; STOP: NOP ; JB P3.7,STOP1 在软件延时中掺插做其他动作 ; SETB P2.7 P2.7←"1" NOP NOP STOP0: NOP RET STOP1: NOP ; JB P3.6,STOP0 在软件延时中掺插做其他动作 ; SETB P2.6 P2.6←"1" RET ; END1: CLR TR0 停止TIMER0 RET ; TIM0: PUSH A 将A的值暂存于堆栈区 PUSH PSW 将PSW的值暂存于堆栈区 MOV TL0,49H 重设计数值 MOV TH0,4AH CPL P1.7 将输出端P1.1取反(P1.7接至无源蜂鸣器) POP PSW 至堆栈区取回PSW的值 POP A 至堆栈区取回A的值 RETI 返回主程序 ; DELAY: MOV R7,#02 187毫秒 D2: MOV R4,#24 D3: MOV R3,#48 DJNZ R3,$ ACALL STOP 在软件延时中掺插做其他动作 DJNZ R4,D3 DJNZ R7,D2 DJNZ R6,DELAY 决定节拍 RET ; .5 .6 .7 1 TABLE1: DW 65111,65150,65199,65217 4M晶振时的定时中断时间常数 ; 2 3 4 5 若采用其它频率,则要根据乐音的 DW 65252,65283,65297,65323 频率计算,例中央C的A音为440Hz, ; 6 7 1` 2` 440Hz=2.273ms,把T0设置为2.273ms DW 65347,65367,65377,65394 中断即可发出A音. ; 3` 4` #6 DW 65410,65417,65357 ; ;*************************************************************** ;* 音符代码 1 2 3 4 5 6 7 8 9 A B C D E F 0 * ;* 音高 .5 .6 .7 1 2 3 4 5 6 7 1` 2` 3` 4` 5` 休止 * ;*-------------------------------------------------------------* ;* 节拍代码 1 2 3 4 5 6 8 A C F * ;* 节拍 1/4 2/4 3/4 1 1(1/4) 1(1/2) 2 2(1/2) 3 3(3/4) * ;*-------------------------------------------------------------* ;* 结束代码 00H * ;*-------------------------------------------------------------* ;* 乐谱格式 每字节的高字节为音符代码,低字节为节拍代码 * ;*-------------------------------------------------------------* ;* 例子: ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ * ;* DB A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H,00H * ;* ⑴ A→唱"7" , 4→ 1 拍 * ;* ⑵ 0→休止 , 2→2/4拍 * ;* ⑶ 8→唱"5" , 4→ 1 拍 * ;* ⑷ 0→休止 , 2→2/4拍 * ;* ⑸ A→唱"7" , 4→ 1 拍 * ;* ⑹ 0→休止 , 2→2/4拍 * ;* ⑺ 8→唱"5" , 4→ 1 拍 * ;* ⑻ 0→休止 , 2→2/4拍 * ;* ⑼ D→唱"3`", 8→ 2 拍 * ;* ⑽ 0→休止 , 4→ 1 拍 * ;* ⑾ 00H→乐曲结束 * ;*************************************************************** ; TABLE: ;【00】 DB 98H,02H,B4H,01H,94H,01H,68H,02H,94H,01H DB 64H,01H,48H,02H,64H,01H,44H,01H,28H,02H DB 64H,01H,94H,01H,B4H,01H,94H,01H,B4H,01H DB 94H,01H,B4H,01H,D4H,01H,94H,01H,64H,01H DB 44H,01H,64H,01H,98H,02H,01H,01H,00H ;【49】 DB A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H DB C8H,01H,01H,01H,01H,01H,00H ;【66】 DB 42H,52H,62H,72H,82H,92H,A2H,B2H,42H,52H DB 62H,72H,82H,92H,A2H,B2H,00H ;【100】 DB 61H,81H,B1H,D1H,B1H,81H,61H,00H ;【108】 DB 11H,41H,61H,81H,61H,41H,11H,00H ;【136】 DB 24H,04H,34H,04H,44H,04H,54H,04H,64H,04H,44H,04H,64H,04H,94H,04H DB 83H,01H,93H,01H,83H,01H,63H,01H,46H,02H,66H,02H DB 91H,21H,91H,21H,91H,21H,91H,21H,94H,00H ;【174】 DB 94H,04H,A4H,04H,B4H,04H,C4H,04H,D4H,04H DB B4H,04H,D8H,08H,C4H,04H,F4H,04H,CCH,00H ; END |