最终选择蜂鸣器电路:显示部分:LM386驱动放大音频电路:
附录:1,不带数码灯的程序
MOV P1,#0FFH
MOV TMOD,#01H
SETB ET0
SETB EA
CLR TR0
START:
MOV R3,P2
CJNE R3,#0FFH,KEY1
CLR TR0
SJMP START
KEY1: ;按键 1 ,P2.0 CJNE R3,#0FEH,KEY2
MOV 30H,#0FBH
MOV 31H,#0E9H
MOV @R0,#0FBH ;将音阶存放到R0,R1对应的地址中
MOV @R1,#0E9H
INC R0
INC R1
LJMP SET_TIMER
KEY2: ;按键2 ,P2.1 CJNE R3,#0FDH,KEY3
MOV 30H,#0FCH
MOV 31H,#5CH
MOV @R0,#0FCH
MOV @R1,#5CH
INC R0
INC R1
LJMP SET_TIMER
KEY3: ;按键3 ,P2.2 CJNE R3,#0FBH,KEY4
MOV 30H,#0FCH
MOV 31H,#0C1H
MOV @R0,#0FCH
MOV @R1,#0C1H
INC R0
INC R1
LJMP SET_TIMER
KEY4: ;按键4 ,P2.3 CJNE R3,#0F7H,KEY5
MOV 30H,#0FCH
MOV 31H,#0EFH
MOV @R0,#0FCH
MOV @R1,#0EFH
INC R0
INC R1
LJMP SET_TIMER
KEY5: ;按键5 ,P2.4 CJNE R3,#0EFH,KEY6
MOV 30H,#0FDH
MOV 31H,#045H
MOV @R0,#0FDH
MOV @R1,#045H
INC R0
INC R1
LJMP SET_TIMER
KEY6: ;按键6 ,P2.5 CJNE R3,#0DFH,KEY7
MOV 30H,#0FDH
MOV 31H,#92H
MOV @R0,#0FDH
MOV @R1,#92H
INC R0
INC R1
LJMP SET_TIMER
KEY7: ;按键7 ,P2.6 CJNE R3,#0BFH,KEY8
MOV 30H,#0FDH
MOV 31H,#0D6H
MOV @R0,#0FDH
MOV @R1,#0D6H
INC R0
INC R1
LJMP SET_TIMER
KEY8: ;按键8,P2.7,用来进入音乐自动播放《生日快乐》
CJNE R3,#7FH,NOKEY
LCALL YYBF ;调用音乐自动播放程序
LJMP SET_TIMER
SET_TIMER:
SETB TR0
LJMP START
NOKEY:
CLR TR0
LJMP START
INT_T0:
MOV TH0,30H
MOV TL0,31H
CPL P1.0
RETI
YYBF:
CLR P1.1
numtim equ 20h
gewei equ 21h
shiwei equ 22h
scanled equ 23h
org 1000h
jmp YYstart
org 001bh
jmp tim0
org 1100h
YYstart: mov tmod,#00010000b
setb ea setb et1
mov numtim,#01h
mov r6,#2h
YYstart0:mov 40h,#00h
next: mov a,40h
mov dptr,#table
movc a,@a+dptr
mov r2,a
jz end0
anl a,#0fh
mov r5,a
mov a,r2
swap a
anl a,#0fh
jnz sing
clr tr1
jmp d1
sing: dec a
mov 22h,a
rl a
mov dptr,#table1
movc a,@a+dptr
mov th1,a
mov 21h,a
mov a,22h
rl a
inc a
movc a,@a+dptr
mov tl1,a
mov 20h,a
setb tr1
d1:lcall delay
inc 40h
jmp next
end0:clr tr1
djnz r6, YYstart0 jmp main
tim0:push acc
push psw
mov tl1,20h
mov th1,21h
cpl p1.0 ;声音频率输出口P1.0
pop psw
pop acc
reti
delay: mov r7,#02h
d2: mov r4,#180
d3: mov r3,#248
djnz r3,$
djnz r4,d3
djnz r7,d2
djnz r5,delay
ret
table1:
dw 64260,64400,64524,64580
dw 64684,64777,64820,64898
dw 64968,65030,65058,65110
dw 65157,65178,65217
table:db 82h,01h,81h,94h,84h
db 0b4h,0a4h,04h
db 82h,01h,81h,94h,84h
db 0c4h,0b4h,04h db 82h,01h,81h,0f4h,0d4h db 0b4h,0a4h,94h
db 0e2h,01h,0e1h,0d4h,0b4h db 0c4h,0b4h,04h
db 00
LYBF1:
MOV 30H,@R0
MOV 31H,@R1
INC R0
INC R1
CLR P0.0 ;调试用
SETB TR0
LCALL DELAY1
CLR TR0
LJMP LYBF1
RET
DELAY1:
MOV R4,#25
LOOP1:
MOV R5,#248
DJNZ R5,$
DJNZ R4,LOOP1
RET
END
附录:2,带数码灯的程序
ORG 0000H ;初始位置00H
JMP STARET ;跳到主程序
ORG 000BH ;定时器0中断起始单元
JMP TIME0 ;跳到中断程序STARET: MOV TMOD,#00000001B;设定工作方式为1
MOV IE, #10000010B ;开中断允许
SETB TR0 L1: CALL KEY ;调用键盘扫描程序
CLR EA ;关中断总允许
JB F0,L1 ;查询键盘按下标志
MOV A,22H ;将键盘码送单元A
MOV DPTR,#TABLE1
MOVC A,@A+DPTR ;将查询的数码管显示码送A
MOV P0,A ;将数码管显
示码送数码管
MOV A,22H ;将键盘码送单元A
RL A ;数据倍乘
MOV DPTR,#TABLE
MOVC A,@A+DPTR;将声音编码送A
MOV TH0,A;将声音编码高位给TH0
MOV 21H,A;送声音编码给21H单元储存
MOV A,22H
RL A
INC A
MOVC A,@A+DPTR;取声音编码地位给A
MOV TL0,A;将声音编码送TL0
MOV 20H,A;将声音编码低位送20H储存
L2: CALL KEY;调用江畔扫描程序
SETB EA;开断总允许
JB F0,L1;查询键盘按下标志
JMP L2 ;没有转L2循环
/*******键盘扫描程序*********/
KEY: SETB F0 ;键盘按下标志至1
MOV R3,#0F7H;R3送扫描码
MOV R1,#00H;R1初始为0
L3: MOV A,R3;将扫描码送A
MOV P2,A将扫描码送P2扫描
MOV A,P2;读取键盘状态
SETB C;进位至1
MOV R5,#04H;将4给R5单元,用于行扫描
L4: RLC A
JNC KEYIN;有键按下跳到KEYIN
INC R1;无键按下R1加1
DJNZ R5,L4;判断一行有没有判断完毕
MOV A,R3;扫描完毕后,再次送扫描码给A
SETB C;进位置1
RRC A;对A进行右移
MOV R3 ,A ;送新的扫描码给R3
JC L3 ;判断是否扫描完毕,是则循环
RET;返回主程序
KEYIN: MOV 22H,R1;将键盘码送22H储存
CLR F0;对键盘按下标志清0
RET;返回主程序
TIME0: PUSH ACC;将A压入堆栈
PUSH PSW;将PSW压入堆栈
MOV TL0,20H;将声音编码低位送TL0
MOV TH0,21H;将声音编码高位送TH0
CPL P1.0;对输出口声音信号取反
POP PSW;.从堆栈还原PSW
POP ACC;从堆栈还原ACC
RETI ;中断返回
/********音符编码***************/ TABLE: DW 64021,64103,64260,64400
DW 64524,64580,64684,64777
DW 64820,64898,64968,65030
DW 65058,65110,65157,65178
/********共阳极数码编码*********/
TABLE1: DB 0CH,98H,48H,40H,1EH
DB 9FH,25H,0DH,99H,49H,41H,1FH
DB 11H,01H,63H,03H
END
音乐发声程序框图如图所示: