/*
程序效果:蜂鳴器發出兩只老虎的音律
*/
ORG 0000H
AJMP START
ORG 000BH
AJMP TIM0
ORG 0030H
START: MOV TMOD,#01H //工作在方式1
MOV IE,#82H //開總控和分控
START0: MOV 30H,#00H //清零
NEXT: MOV A,30H //清零
MOV DPTR,#TABLE //賦表首地址
MOVC A,@A+DPTR
MOV R2,A //暫存A的值
JZ END0 //判斷A是否為0
ANL A,#0FH //屏蔽A的高半
MOV R5,A //把A屏蔽高半的值賦給R5
MOV A,R2 //恢復A的原值
SWAP A //高低位互換
ANL A,#0FH //屏蔽原來A的高半
JNZ SING //判斷原來A的高半是否為0
CLR TR0 //是0,則停止計時
SETB P2.0 //關閉蜂鳴器
LJMP D1 //轉到標號為D1的地方
//原來A的高半不為零,開始唱歌
SING: DEC A //¥原來A的高半減1,用于讀取相應的音律
MOV 22H,A //¥保存現在A的值
RL A //¥左循環移位
MOV DPTR,#TABLE1 //賦表首地址
MOVC A,@A+DPTR
MOV TH0,A //賦給TH0用于計時,用于控制蜂鳴器響的時間
MOV 21H,A //保存A的值
MOV A,22H //*
RL A //左循環移位
INC A //加1,根據表的存儲順序
MOVC A,@A+DPTR
MOV TL0,A //用于把低八位賦給TL0,用于計時
MOV 20H,A //*
SETB TR0 //啟動定時器
D1: LCALL DELAY //調用延時子程序,能夠聽到該音律
INC 30H //加1
LJMP NEXT
END0: CLR TR0 //停止計時
JMP START0 //無限循環
//定時器0
TIM0: PUSH ACC //保護A的值
PUSH PSW
MOV TL0,20H //賦初值
MOV TH0,21H
CPL P2.0 //給蜂鳴器高低電平,使蜂鳴器發聲
POP PSW //彈出相應的值
POP ACC
RETI //返回
//延時時間大約為:100ms=0.1s
DELAY: MOV R4,#187
D3: MOV R3,#248
DJNZ R3,$
DJNZ R4,D3
DJNZ R5,DELAY //R5代表節拍
RET
TABLE1: DW 63745,63969,64140,64215 //$ ;七個音符
DW 64360,64489,64603 //$ 他們之間存在一種對應關系
TABLE: DB 14H,24H,34H,14H,01H //$
DB 14H,24H,34H,14H,01H //$
DB 34H,44H,54H,02H,34H,44H,54H,02H //$
DB 52H,62H,52H,42H,34H,14H,01H,52H,62H,52H,42H,34H,14H,02H //$
DB 14H,54H,14H,02H,14H,54H,14H,08H,00H //$
END
/*
注:程序源于查老師
完整程序:http://www.zg4o1577.cn/ziliao/file/lzlhasm.rar
*/