急求用89c51单片机 音乐两只老虎的汇编程序及仿真原理图 谢谢!

2024-11-21 16:30:02
推荐回答(2个)
回答(1):

那个程序刚刚给你找了好久才找到,呵呵

   HUAN BIT 20H

   ORG 0000H

   JMP MAIN

   ORG 000BH

   MOV TL0,R2

   MOV TH0,R3

   CPL P3.5

   RETI

     

   ORG 001BH

   DJNZ R4,GOON

   MOV IE,#80H

   JMP T1END

GOON: MOV TL1,#3CH

   MOV TH1,#0B0H

T1END: RETI

    ORG 0100H

MAIN: MOV R5,#99H

LOOP: MOV TMOD,#11H

    MOV IP,#02H

   MOV TH0,#3CH

   MOV TL0,#0B0H

   SETB EA

NEXT: MOV DPTR,#TAB

     MOV R1,#00H

L1:   MOV A,R1

   MOVC A,@A+DPTR

   MOV R3,A

   JZ L3

   INC R1

   MOV A,R1

   MOVC A,@A+DPTR

   MOV R2,A

   XRL A,#0FFH

   JNZ L4

   MOV A,R3

   XRL A,#0FFH

   JZ L5

L4:   INC R1

     MOV A,R1

L3:   MOVC A,@A+DPTR

   MOV R4,A

   MOV TH0,R3

   MOV TL0,R2

   SETB ET0

   SETB TR0

   SETB ET1

   SETB TR1

   SETB HUAN

   JB HUAN,$

   INC R1

   CJNE R1,#00H,L2

   INC DPH

L2:   JMP L1

L5:   DJNZ R5,LOOP

      JMP $

TAB:  DB 0FBH,0F9H,08H,0FCH,066H,08H,0FCH,0C7H,08H,0FBH,0F9H,08H

   DB 0FBH,0F9H,08H,0FCH,066H,08H,0FCH,0C7H,08H,0FBH,0F9H,08H

   DB 0FCH,0C7H,08H,0FCH,0F3H,08H,0FDH,0A4H,10H,0FCH,0C7H,08H

   DB 0FCH,0F3H,08H,0FDH,04AH,08H,0FDH,04AH,04H,0FDH,095H,04H

   DB 0FDH,04AH,04H,0FCH,0F3H,04H,0FCH,0C7H,08H,0FBH,0F9H,08H

   DB 0FDH,04AH,04H,0FDH,095H,04H,0FDH,4AH,08H,04H,0FCH,0FCH,04H

   DB 0FCH,0C7H,08H,0FBH,0F9H,08H,0FCH,066H,08H,0FAH,093H,08H

   DB 0FBH,0F9H,08H,00H,08H,0FCH,66H,04H,0FAH,093H,08H

   DB 0FBH,0F9H,08H,00H,10H,0FFH,0FFH 

   END

回答(2):

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.3 //给蜂鸣器高低电平,使蜂鸣器发声
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