|
ORG 00H
JMP START ;转初始化程序
ORG 01BH
JMP TIM0 ;中断进口
START: MOV TMOD, #10H ;定时器1启动方式1
MOV IE, #88H ;定时器1开中断
START0: MOV 30H, #00 ;歌曲播放主程序,30暂存偏移量
NEXT: CALL CKEY ;调用键盘扫描
JB F0, LK2 ;确认按键标志为1即有按键转按键处理
MOV A, 30H ;无按键,送偏移量
MOV DPTR, #TABLE ;载入音符基地址
MOVC A, @A+DPTR ;取音符
MOV R2, A ;音符暂存R2
JZ END0 ;音符为00即唱完一篇,转结束处理
ANL A, #0FH ;屏蔽高4位
MOV R5, A ;拍子送R5
MOV A, R2 ;重取音符
SWAP A ;高低四位交换
ANL A, #0FH ;屏蔽高四位
JNZ SING ;不为0,转发音程序
CLR TR1 ;为0,不发音,关闭定时器
JMP D1 ;转调用拍子延时程序
SING: DEC A ;算出发音偏移量
MOV 22H, A ;偏移量送22H暂存
RL A ;左移×2(因每个发音频率占2个字节)
MOV DPTR, #TABLE1 ;载入音频表基地址
MOVC A, @A+DPTR ;取出频率高8位
MOV TH1, A ;频率高8位送定时器高8位
MOV R1, A ;并送R1寄存
MOV A, 22H ;重取偏移量
RL A ;左移
INC A ;+1指向频率低8位
MOVC A, @A+DPTR ;取出频率低8位
MOV TL1, A ;频率低8位送定时器低8位
MOV R0, A ;并送R0寄存
SETB TR1 ;定时器启动
MOV A, 22H ;重取偏移量
MOV DPTR, #TABLE2 ;载入数字表基地址
MOVC A, @A+DPTR ;取出欲显示数字
MOV P2, A ;送LED管显示
D1: CALL DELAY ;调用拍子延时程序
SETB P3.4 ;置高电平,可去除喇叭杂音
MOV P2, #0FFH ;熄灭LED显示管
INC 30H ;指向下一个音符
JMP NEXT ;转下一个音符
END0: CLR TR1 ;关闭中断
JMP START0 ;转歌曲查表程序,重新开始
DELAY: MOV R7, #02 ;拍子延时程序
D2: MOV R4, #187
D3: MOV R3, #248
DJNZ R3, $
DJNZ R4, D3
DJNZ R7, D2 ;到这里为1/4拍
DJNZ R5, DELAY ;由音符拍子确定发音时间长度
RET
CKEY: SETB F0 ;键盘扫描程序,F0先置1
MOV P1, #0FH ;置P1口低4位为输入状态
MOV A, P1 ;读P1口
ANL A, #0FH ;屏蔽低4位
CJNE A, #0FH, L1 ;有按键转L1
SJMP L2 ;无按键转回,并置F0为0标志
L1: CALL DELAY1 ;调用去抖延时
MOV P1, #0FH
MOV A, P1
ANL A, #0FH
CJNE A, #0FH, L3 ;再次确认有无按键,有转返回
L2: CLR F0 ;无按键,F0置0标志
L3: RET ;返回
LK1: CALL CKEY ;调用键盘扫描程序
JB F0, LK2 ;判F0按键标志,有按键转键号计算
CLR TR1 ;无按键,关闭定时器
SJMP LK1 ;转回继续扫描
LK2: MOV R4, #00H ;首列号送R4
MOV R2, #0EFH ;从首列开始扫描
LK4: MOV A, R2
MOV P1, A
MOV A, P1
JB ACC.0, LONE ;第0行无按键按下,转查第1行
MOV A, #00H ;有按键按下送首键号A
AJMP LKP ;转求键号
LONE: JB ACC.1, LTOW ;第1行无按键按下,转查第2行
MOV A, #04H ;有按键按下送首键号A
AJMP LKP ;转求键号
LTOW: JB ACC.2, LTHE ;第2行无按键按下,转查第3行
MOV A, #08H ;有按键按下送首键号A
AJMP LKP ;转求键号
LTHE: JB ACC.3, NEXT1 ;第3行无按键按下,转查下1列
MOV A, #0CH ;有按键按下送首键号A
AJMP LKP ;转求键号
NEXT1: INC R4
MOV A, R2 ;取列号
JNB ACC.7, KND ;判4列扫描完没有
RL A ;未完,扫描字对应下一列
MOV R2, A
AJMP LK4 ;转下1列扫描
LKP: ADD A, R4 ;求键号(键号=首行键号+列号)
MOV R3, A ;键号(即偏移量)送R3寄存
RL A ;左移
MOV DPTR, #TABLE1 ;载入音频表基地址
MOVC A, @A+DPTR ;取出频率高8位
MOV R1, A ;送R1寄存
MOV TH1, A ;送定时器高8位
MOV A, R3 ;重取键号
RL A
INC A ;指向低8位
MOVC A, @A+DPTR ;取出频率低8位
MOV R0, A ;送R0寄存
MOV TL1, A ;送定时器低8位
SETB TR1 ;启动定时器
MOV A, R3 ;重取键号
MOV DPTR, #TABLE2 ;载入数字表基地址
MOVC A, @A+DPTR ;取出欲显示数字
MOV P2, A ;送P2口显示
LKP1: CALL CKEY ;调用键盘扫描
JB F0, LKP1 ;等待键释放
SETB P3.4 ;键释放后置喇叭高电平,去杂音
MOV P2, #0FFH ;熄灭LED显示
CLR TR1 ;关闭中断
KND: AJMP LK1 ;重转键盘扫描
TIM0:
PUSH ACC
PUSH PSW
MOV TL1, 20H ;喇叭发音中断程序
MOV TH1, 21H
CPL P3.4 ;取反
POP PSW
POP ACC
RETI
DELAY1: MOV R5 , #2DH ;去抖延时子程序
BB: MOV R7 , #0FFH
AA: DJNZ R7 , AA
DJNZ R5 , BB
RET
TABLE1: ;音频表
DW 64021,64103,64260,64400
DW 64524,64580,64684,64777
DW 64820,64898,64968,65030
DW 65058,65110,65157,65170
TABLE2: ;LED显示的数字表
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH
TABLE: ;歌曲音符表(歌曲:祝你平安)
DB 26H,20H,20H,20H,20H,20H,26H,10H,20H,10H,20H,80H,26H,20H,30H,20H
DB 30H,20H,39H,10H,30H,10H,30H,80H,26H,20H,20H,20H,20H,20H,1cH,20H
DB 20H,80H,2bH,20H,26H,20H,20H,20H,2bH,10H,26H,10H,2bH,80H,26H,20H
DB 30H,20H,30H,20H,39H,10H,26H,10H,26H,60H,40H,10H,39H,10H,26H,20H
DB 30H,20H,30H,20H,39H,10H,26H,10H,26H,80H,26H,20H,2bH,10H,2bH,10H
DB 2bH,20H,30H,10H,39H,10H,26H,10H,2bH,10H,2bH,20H,2bH,40H,40H,20H
DB 20H,10H,20H,10H,2bH,10H,26H,30H,30H,80H,18H,20H,18H,20H,26H,20H
DB 20H,20H,20H,40H,26H,20H,2bH,20H,30H,20H,30H,20H,1cH,20H,20H,20H
DB 20H,80H,1cH,20H,1cH,20H,1cH,20H,30H,20H,30H,60H,39H,10H,30H,10H
DB 20H,20H,2bH,10H,26H,10H,2bH,10H,26H,10H,26H,10H,2bH,10H,2bH,80H
DB 18H,20H,18H,20H,26H,20H,20H,20H,20H,60H,26H,10H,2bH,20H,30H,20H
DB 30H,20H,1cH,20H,20H,20H,20H,80H,26H,20H,30H,10H,30H,10H,30H,20H
DB 39H,20H,26H,10H,2bH,10H,2bH,20H,2bH,40H,40H,10H,40H,10H,20H,10H
DB 20H,10H,2bH,10H,26H,30H,30H,80H,00H
END
这程序哪里错了
怎么不能正常执行啊,只会一直嘟嘟的响
|
|