51单片机控制蜂鸣器播放5首歌曲汇编程序
OVER:
;TO_OVER: JMP INT_OVER
;---------------------------
;SELECT: DEC NUM
;MOV A, NUM
;ANL A, #0F0H
;JNZ TO_OVER
;MOV A, NUM
;CLR C
;SUBB A, #11
;JNC TO_OVER
;MOV A, NUM
;RL A
;MOV TAB_1, A
;MOV TAB_2, TAB_1
;INC TAB_2
;MOV DPTR, #TAB_SPEED ;查乐曲速度
;MOV A, TAB_1
;MOVC A, @A+DPTR
;MOV PERIOD_L, A
;MOV TL0, A
;MOV A, TAB_2
;MOVC A, @A+DPTR
;MOV PERIOD_H, A
;MOV PERIOD_TEMP, A
;MOV TH0, A
;MOV DPTR, #TAB_NUM_T ;查音高位置首地址
;MOV A, TAB_1
;MOVC A, @A+DPTR
;MOV TAB_TONE_H, A
;MOV A, TAB_2
;MOVC A, @A+DPTR
;MOV TAB_TONE_L, A
;MOV DPTR, #TAB_NUM_L ;查音长位置首地址
;MOV A, TAB_1
;MOVC A, @A+DPTR
;MOV TAB_H, A
;MOV A, TAB_2
;MOVC A, @A+DPTR
;MOV TAB_L, A
;HANDLE: JB FLAG_F, PLAY_0 ;演奏乐曲时跳转
;SETB FLAG_P ;允许播放
;MOV POSITION, #0H ;赋乐曲位置值为0,即从头开始拨出
;MOV COUNTER, #02H
;MOV CU_COUNTER, COUNTER ;赋当前定时次数和应定时次数值,使之相等,以使定时器工作时就播放,无需等待
;MOV COUNTER_1, COUNTER
;DEC COUNTER_1
;CLR FLAG_LAST
;MOV COUNTER_LOOP, #0
;SETB TR0 ;启动定时器0
;JMP INT_OVER
;PLAY_0: CLR P3.7
;SETB FLAG_PRESS
;SETB FLAG_CH
;MOV DPTR, #TAB_TONE ;查音高表
;MOV A, NUM
;ADD A, #07
;RL A ;音高表每组音高有两个延时值
;MOV TAB_1, A
;MOVC A, @A+DPTR ;查第一个延时值
;MOV D_1, A
;MOV A, TAB_1
;INC A
;MOVC A, @A+DPTR
;MOV D_2, A
;JB FLAG_L, L_0
;SETB FLAG_L
;CLR P3.4
;SETB P3.3
;JMP INT_OVER
;L_0: CLR FLAG_L
;CLR P3.3
;SETB P3.4
;INT_OVER: POP ACC
;RETI
;****************定时器0中断服务程序****************
INT_T: PUSH ACC
CLR TR0
MOV TH0, PERIOD_H
MOV TL0, PERIOD_L
MOV A, CU_COUNTER
CJNE A, COUNTER_1, GO_ON_1
SETB FLAG_LAST
JMP READ
GO_ON_1: CJNE A, COUNTER, GO_ON ;音符时间未到跳转
CLR FLAG_LAST
MOV DPH, TAB_H ;读取音长表首地址
MOV DPL, TAB_L
MOV A, POSITION
MOVC A, @A+DPTR
MOV COUNTER, A
MOV COUNTER_1, A
DEC COUNTER_1
READ: MOV DPH, TAB_TONE_H ;读取音高表首地址
MOV DPL, TAB_TONE_L
MOV A, POSITION ;查音高值
MOVC A, @A+DPTR
JNB FLAG_LAST, NO_LAST
SUBB A, #07
NO_LAST: MOV TONE, A
MOV DPTR, #TAB_TONE ;查与音高相对印的延时值
MOV A, TONE ;查第一个延时值
SUBB A, #06H
RL A
MOVC A, @A+DPTR
MOV D_1, A
MOV A, TONE ;查第二个延时值
SUBB A, #06H
RL A
INC A
MOVC A, @A+DPTR
MOV D_2, A
JB FLAG_LAST, GO_ON_INC
INC POSITION
MOV CU_COUNTER, #01H
MOV A, TONE
JZ INT_T_OVER
JB FLAG_L, LT_0
SETB FLAG_L
CLR P3.4
SETB P3.3
JMP INT_T_OVER
LT_0: CLR FLAG_L
CLR P3.3
SETB P3.4
JMP INT_T_OVER
GO_ON_INC: MOV A, TONE
ADD A, #07
MOV TONE, A
GO_ON: INC CU_COUNTER
INT_T_OVER:
INC COUNTER_LOOP ;行走控制
MOV A, COUNTER_LOOP
CJNE A, #16, IF_GO
ORL P1, #0FH
JMP R
IF_GO: CJNE A, #25, IF_32
MOV A, TONE
; JZ R
MOV A, COUNTER
CLR C
SUBB A, #64
JC YES ;音长大于等于64时停止行走
MOV A, COUNTER
SUBB A, CU_COUNTER
CLR C
SUBB A, #33
JC YES
JMP R
YES: JB FLAG_GO, GO_1 ;不允许行走跳转
ORL P1, #0FH
JMP R
GO_1: JB STAT_0, GO_2 ;行走一步
SETB P1.0
SETB STAT_0
CLR P1.1
CLR STAT_1
JMP R
GO_2: JB STAT_1, GO_3
SETB P1.1
SETB STAT_1
CLR P1.2
CLR STAT_2
JMP R
GO_3: JB STAT_2, GO_4
SETB P1.2
SETB STAT_2
CLR P1.3
CLR STAT_3
JMP R
GO_4: SETB P1.3
SETB STAT_3
CLR P1.0
CLR STAT_0
JMP R
IF_32: MOV A, COUNTER_LOOP
CJNE A, #32, R
MOV COUNTER_LOOP, #00H
R: SETB TR0
POP ACC
RETI
;******************外部中断0服务程序*******************
INT_0: PUSH ACC
POP ACC
RETI
;******************长延时子程序(1S)*******************
LONG: MOV D_L1, P_L1
DL1: MOV D_L2, P_L2
DL2: MOV D_L3, #0FFH
DL3: DJNZ D_L3, DL3
DJNZ D_L2, DL2
DJNZ D_L1, DL1
MOV P_L1, #01H
RET
;*******************延时子程序**********************
DELAY: MOV P_1, D_1
D1: MOV P_2, D_2
D2: DJNZ P_2, D2
DJNZ P_1, D1
RET
;---------------音长表--------------------
;以64分音符为一个单位,即1为64分音符、2为32分...
TAB_L0: DB 32,16,16,32,16,16,32,16,16,24,8,64 ;《DINGO BELL 》
DB 16,16,32,16,16,32,16,16,16,16,64
DB 16,16,32,16,16,32,16,16,24,8,64
DB 16,16,32,16,16,32,16,16,16,16,32,32
TAB_L1: DB 32,32,32,32,32,32,32,32,32,32,32,32,32,48,16,64 ;
51单片机蜂鸣器汇编程 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)