📄 test.asm
字号:
ACALL CNDATA
NOP
MOV R5,CVER
NOP
AJMP TT_VOLUP
SB_VOLDN: ;重低音递减
MOV A,SVER
JZ LOOP_E
MOV PHONE,SVER
ACALL DAA
NOP
MOV SVER,PHONE
MOV PHONE,S_UB
ACALL UAA
NOP
MOV S_UB,PHONE
ACALL SBDATA
NOP
MOV R5,SVER
NOP
AJMP TT_VOLUP
;-----------------------------------------------------------
;按音量加减给2258数据入口
FRDATA: ;前置音量2258入口数据
MOV A,FRONT ;FRONT是16进制数,如#34H
SWAP A
ANL A,#0FH ;保留FRONT的高4位不变
ADD A,#60H ;加#60H,2258(0110 0011通道5FR,-10DB/STEP
MOV 30H,A ;现在是通道FL-30DB
MOV A,FRONT
ANL A,#0FH ;保留FRONT的低4位
ADD A,#70H ;加#70H,2258(0111 0100通道5FR,-1DB/STEP
MOV 31H,A ;现在为-4DB
MOV NUMBYT,#02H ;要传给2258,16位
CALL WRNBYT ;调I2C
NOP
MOV A,FRONT
SWAP A
ANL A,#0FH ;保留高4位
ADD A,#0A0H ; ;2258(0010 0100通道4FL,-10DB/STEP
MOV 30H,A
MOV A,FRONT
ANL A,#0FH
ADD A,#0B0H ;2258(0011 0100通道4FL,-1DB/STEP
MOV 31H,A ;
MOV NUMBYT,#02H ;调4通道FL
LCALL WRNBYT
NOP
RET
RRDATA: ;环绕音量2258入口数据处理
MOV A,REAR
SWAP A
ANL A,#0FH
ADD A,#80H ;2258(1000 0100通道1SL-10DB/STEP)
MOV 30H,A
MOV A,REAR
ANL A,#0FH
ADD A,#90H ;2258(1001 0100通道1SL-1DB/STEP)
MOV 31H,A
MOV NUMBYT,#02H
CALL WRNBYT
NOP
MOV A,REAR
SWAP A
ANL A,#0FH
ADD A,#40H ;2258(0100 0100通道2SR-10DB/STEP)
MOV 30H,A
MOV A,REAR
ANL A,#0FH
ADD A,#50H ;2258(0101 0100通道2SR-1DB/STEP)
MOV 31H,A
MOV NUMBYT,#02H
LCALL WRNBYT
NOP
RET
CNDATA: ;中置音量2258入口数据处理
MOV A,CEN
SWAP A
ANL A,#0FH
ADD A,#00H ;2258(0000 0100通道3CEN-10DB/STEP)
MOV 30H,A
MOV A,CEN
ANL A,#0FH
ADD A,#10H ;2258(0001 0100通道3CEN-1DB/STEP)
MOV 31H,A
MOV NUMBYT,#02H
LCALL WRNBYT
NOP
RET
SBDATA: ;重低音2258入口数据处理
MOV A,S_UB
SWAP A
ANL A,#0FH
ADD A,#20H ;2258(0010 0100通道4SW-10DB/STEP)
MOV 30H,A
MOV A,S_UB
ANL A,#0FH
ADD A,#30H ;2258(0011 0100通道4SW-1DB/STEP)
MOV 31H,A
MOV NUMBYT,#02H
LCALL WRNBYT
NOP
RET
;-----------------------------------------------------------
DISP_VOL: ;保持音量显示级数不调节就不变
MOV A,R5
SWAP A
ANL A,#0FH
MOV DISPBUFF1,A ;十位到DISPBUFF1
MOV A,R5
ANL A,#0FH
MOV DISPBUFF2,A ;个位到DISPBUFF2
RET
;-----------------------------------------------------------
UAA: ;实现PHONE的两位数值十进制递增1
MOV A,PHONE
SWAP A
ANL A,#0FH
MOV R5,A
MOV A,PHONE
ANL A,#0FH
NOP
CJNE A,#09H,UAA_1 ;到9就要变了
NOP
MOV R4,#00H
INC R5 ;十位加1
AJMP UAA_2
UAA_1: INC A
MOV R4,A
UAA_2: MOV A,R5
SWAP A
ADD A,R4
MOV PHONE,A
RET
;-----------------------------------------------------------
DAA: ;实现PHONE的两位数值十进制递减1
MOV A,PHONE
SWAP A
ANL A,#0FH ;
MOV R5,A ;
MOV A,PHONE ;
ANL A,#0FH
JNZ DAA_1 ;A≠0就转移,把A-1,只减个位
MOV R4,#09H ;A=0则R4=#09H
DEC R5 ;且把R5-1即十位减1
NOP
SJMP DAA_2 ;跳转
DAA_1: DEC A
MOV R4,A
DAA_2: ;十个位复原但十进制减1
MOV A,R5 ;
SWAP A
ADD A,R4
MOV PHONE,A
RET
;定时器T1入口
;--------------------------数码管显示程序-------------------
DISP: PUSH ACC ;保护现场
PUSH PSW
MOV PSW,#00H ;程序状态重赋值
MOV TH1,#0E8H ;定时器1赋初值
MOV TL1,#30H
SETB P3.5 ;数码管和指示灯都关掉
SETB P3.7
SETB P1.0
INC NO_N
MOV A,NO_N
XRL A,#9FH
JNZ NONTE
MOV NO_N,#80H
NONTE: INC R2
MOV A,R2
XRL A,#5AH
JNZ DE ;R2不等于#5AH就跳出去显示数码管
MOV R2,#00H ;清R2
INC R3
JB (29H).1,LED_1 ;
MOV A,DISPBUFF3
XRL A,#10000000B
MOV DISPBUFF3,A
NOP
AJMP LED_11
LED_1: MOV A,DISPBUFF3
ORL A,#10000000B
MOV DISPBUFF3,A
LED_11: JNB (29H).2,LED_2
MOV A,DISPBUFF3
XRL A,#00010000B
MOV DISPBUFF3,A
LED_2: JNB (29H).3,LED_3
MOV A,DISPBUFF3
XRL A,#01000000B
MOV DISPBUFF3,A
LED_3: JNB (29H).4,LED_4
MOV A,DISPBUFF3
XRL A,#00000010B
MOV DISPBUFF3,A
LED_4: JNB (29H).5,DE
MOV A,DISPBUFF3
XRL A,#00000100B
MOV DISPBUFF3,A
DE: MOV A,COUNTER ;看记数器的值
JNZ DE_1 ;不等于0就跳转
MOV A,DISPBUFF2 ;等于0就把个位数入A查表将值送到P1口
MOV DPTR,#TAB1 ;如DISPBUFF2=5,则查表后P1口44H显示5
MOVC A,@A+DPTR
MOV P1,A ;P1.0都=0相当于开了个位的位控制
NOP
AJMP DISPNEXT
DE_1: XRL A,#01H ;计数器=1吗
JNZ DE_2 ;不=1就跳转
MOV A,DISPBUFF1 ;等于1就把十位数调出来显示
MOV DPTR,#TAB2
MOVC A,@A+DPTR
MOV P1,A ;P1.0都=1,相当于关着个位显示
CLR P3.7 ;开十位显示
NOP
AJMP DISPNEXT ;计数器去控制
DE_2: ;计数器到2了,显示指示灯
MOV P1,DISPBUFF3 ;把指示灯的值送P1口
CLR P3.5 ;因DISPBUFF3是逻辑运算后得的,显示与数码管不同
DISPNEXT: INC COUNTER ;记数器加1
MOV A,COUNTER
XRL A,#03H ;计数器不能大于3
JNZ DISPEXIT ;不等于3就跳出
MOV COUNTER,#00H ;等于3让它回到0
DISPEXIT: ;保护出栈
POP PSW
POP ACC
RETI
;--------------------------数码管段码表---------------------
TAB1: DB 10H,7CH,88H,28H,64H
DB 22H,02H,78H,00H,20H
TAB2: DB 11H,7DH,89H,29H,65H
DB 23H,03H,79H,01H,21H
;DB 03H,0CFH,2AH,4AH,0C6H,52H,12H,0CBH,02H,42H
;0 1 2 3 4 5 6 7 8 9
;======================PT2258的I2C控制======================
WRNBYT: PUSH ACC ;保护现场
PUSH PSW
MOV PSW,#18H ;PSW赋值R0=08H,R1=09H,原来R0=00H,R1=01H)
;寄存器第1组(CY=1,AC=0,F0=0,RS1=0,RS1=1,0V=0,X=0,P=0)
WRNBYT1: NOP
LCALL STA ;启动
NOP
MOV A,#88H ;2258地址
NOP
LCALL WRBYT ;发送字节数据
NOP
LCALL CACK ;调用检测应答位子程序
NOP
JB F0,WRNBYT1 ;判断应答位
MOV R1,#MTD ;有应答把缓冲2258数据存放首地址30H
;放入R1=08H寄存器,30H内是各操作状态
;给的数
WRDA: MOV A,@R1 ;(30H内的值放入A)
NOP
LCALL WRBYT ;送字节
NOP
LCALL CACK ;应答
NOP
JB F0,WRNBYT1 ;F0=1有应答再来
INC R1 ;(送30H内的数,有些动作要送31H内的数)
DJNZ NUMBYT,WRDA ;(NUMBYT=1就向下执行
;=2就传16位到总线上给2258)
NOP
LCALL STOP ;结束I2C
NOP
POP PSW ;PSW,ACC出栈,用过ACC,PSW的C,F0,R0,R1等)
POP ACC ;要恢复现场
RET
;----------------------2258主程序完毕-----------------------
;I2C总线启动(启动条件: SCL为高电平,SDA由高变低)
SETB SDA
NOP
NOP
SETB SCL
WAITS: ;确保启始条件,满足建立时间要大于4.7US
JNB SCL,WAITS ;SCL没高就等
NOP ;5个NOP比较好
NOP
NOP
NOP
CLR SDA
NOP ;启始条件锁定时间大于4US,5个NOP就可以吧
NOP
NOP
NOP
NOP
NOP
CLR SCL ;锁住总线,准备发数据
NOP
RET
;结束I2C总线(停止信号: SCL为高电平,SDA由高变低)
CLR SDA
NOP
NOP
SETB SCL ;发送结束条件的时钟信号
WAITP: JNB SCL,WAITP ;确保时钟为高否则等待
NOP ;结束总线时间大于4US
NOP
NOP
NOP
SETB SDA ;结束总线
NOP ;保证一个终止信号和下一个起始信号空闲时间
NOP ;大于4.7US
NOP
NOP
NOP
NOP
CLR SCL ;锁住总线
NOP ;
RET
CACK: ;检查应答位子程序
SETB SDA
NOP
NOP
SETB SCL
NOP
CLR F0 ;应答标志位(F0是用户标志位,可由程序员决定
;何时使用: ))
JNB SDA,CEND ;判断应答位
SETB F0
CEND: NOP
CLR SCL
NOP
NOP
NOP
NOP
RET
;-----------------------------------------------------------
WRBYT: ;把各操作状态给30H,31H的数写入
MOV R0,#07H
RLC A ;取数据位(30H内的值左移,无进位还没写完又开始
;有进位表示写完8位就结束)
JC NEXT1 ;(CY=1就转移,CY本来就为1,8位写完有进位应该=0)
CLR SDA ;结束I2C状态
NOP
NOP
SJMP NEXT0
NEXT1: SETB SDA ;保持开始I2C状态
NOP
NOP
NEXT0: SETB SCL
WAITW: JNB SCL,WAITW ;确保SCL=1,SCL=0就等待SCL=1
NOP ;启动建立时间要大于4.7US,不同晶体要改NOP个数)
NOP
NOP
NOP
CLR SCL ;又钳主总线,等发数据
NOP
NOP
CLR SDA ;SDA变低就开始发字节0,1
WLP: ;发送字节子程序
RLC A ;取数据位
JC WR1 ;如果进位为1则写入1,进位为0写入的是0
;一个一个慢慢左移进CY
NOP
AJMP WR0 ;判断数据位,是0就执行写0
WLP1: DJNZ R0,WLP ;写8位就退出
RET
WR1: ;发送1
SETB SDA ;数据为高即1准备写入
NOP
NOP
SETB SCL ;要时钟在高电平周期才认为有效
NOP ;周期
NOP
NOP
NOP
NOP
NOP
CLR SCL ;有效后要恢复SCL,SDA状态
NOP ;SCL变低
NOP
CLR SDA ;SDA变低,为何要变低?因为下一位有可能为0
NOP
NOP
AJMP WLP1 ;准备写下一位
WR0: ;发送0
CLR SDA ;数据为低即准备写入0
NOP
NOP
SETB SCL ;时钟要为高电平
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL ;写完0让SCL变低,只有在SCL为低时,SDA才可变化
NOP ;下一位如果为1就是变化,I2C规定的
NOP
LJMP WLP1 ;准备写下一位
;----------------------延时50MS-----------------------------
DELAY: MOV R7,#255
D2: MOV R6,#200
DJNZ R6,$
DJNZ R7,D2
RET
;///////////////////////////////////////////////////////////
CLMUT: ;2258静音
JB (29H).1,CLMUT_EX ;(29H).1=1就退出
SETB (29H).1 ;否则
MOV 30H,#0F8H ;1111 1000,2258 NO MUTE
MOV NUMBYT,#01H
NOP
ACALL WRNBYT ;写入2258
NOP
CLMUT_EX: RET
;----------------------外中断1入口--------------------------
INO1: ;有遥控信号引发外中断1
PUSH ACC ;压栈ACC,累加器内容保护
PUSH PSW ;压栈PSW,程序状态字保护
MOV PSW,#10H ;寄存器选第一组
CLR TR0 ;关定时
CLR EX1 ;把外中断1关掉
MOV 27H,TH0 ;定时0初值放入暂存
MOV 28H,TL0
MOV TH0,#00H ;定时初值
MOV TL0,#00H
SETB TR0 ;开定时
JNB (29H).0,REST_12 ;跳转
MOV 4AH,27H
MOV 4BH,28H
MOV 4CH,#03H ;定时器0设定比较值#039DH(3X16X16+9X16+13=925=0.925MS)
MOV 4DH,#9DH
NOP
LCALL SUB0 ;
NOP
JC X1_009 ;
MOV 4CH,#05H ;时间1.325MS,避过2.25MS连发码
MOV 4DH,#2DH
MOV 4AH,27H
MOV 4BH,28H
NOP
LCALL SUB0
NOP
JNC X1_01
CLR C ;否则收到0
NOP
LJMP X1_02
X1_009: NOP
AJMP X1_005
X1_OO1: NOP
AJMP X1_OUT1
REST_12: NOP
AJMP REST_1
X1_01: MOV 4CH,#07H ;2MS
MOV 4DH,#0D0H
MOV 4AH,27H
MOV 4BH,28H
NOP
LCALL SUB0
NOP
JC X1_009
MOV 4CH,#09H ;2.5MS
MOV 4DH,#0C4H
MOV 4AH,27H
MOV 4BH,28H
NOP
LCALL SUB0
NOP
JC X_01T
NOP
AJMP X1_005
X_01T: NOP
AJMP X_01
;-----------------------------------------------------------
REST_1: MOV 4CH,#2AH
MOV 4DH,#0F8H
MOV 4AH,27H
MOV 4BH,28H
NOP
LCALL SUB0
NOP
JC X1_009
MOV 4CH,#2EH
MOV 4DH,#0E0H
MOV 4AH,27H
MOV 4BH,28H
NOP
LCALL SUB0
NOP
JNC REST_2
MOV 4CH,#03H
MOV 4DH,#08H
MOV 4AH,#03H
MOV 4BH,NO_N
NOP
LCALL SUB0
NOP
JC X1_005
MOV 4CH,#03H
MOV 4DH,#1EH
MOV 4AH,#03H
MOV 4BH,NO_N
NOP
LCALL SUB0
NOP
JNC X1_005
MOV NO_N,#00H
DJNZ REMVOL,X1_005
MOV REMVOL,#01H
MOV A,2CH
XRL A,#00H
JNZ REST_3
NOP
AJMP X1_10
;...略,详细见套件所配程序
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -