📄 project(9.18).asm
字号:
;A为带出实参。其内容为插入位置.
;*****************************************************************
DATAMOV:
PUSH 00H
PUSH 01H
MOVX A,@R1
MOV B,A
DATAMOV1:
MOVX A,@R0
CJNE A,0F0H,DATAMOV2
SJMP DATAMOV4
DATAMOV2:
JNC DATAMOV4 ;若L.r[0].key<=L.r[j].key,中止循环
DATAMOV3:
MOVX A,@R0 ;否则,L.r[j+1]=L.r[j]
MOVX @R1,A
INC R0
INC R1
MOVX A,@R0 ;将行号也相应移动
MOVX @R1,A
DEC R0 ;回到数据位
DEC R1
DEC R0 ;跳到前一组的数据位
DEC R0
DEC R1
DEC R1
SJMP DATAMOV1
DATAMOV4:
MOV A,R1 ;将插入地址赋给A传出
POP 01H
POP 00H
RET
;*******************************************************
;除法子程序 CALL BY MATEE
;入口条件:若被除数为双字节,高字节在B中,低字节在A中。
; 否则,被除数在A中。除数在R6中
;出口信息:商在A中
;*******************************************************
DIVIDE:
PUSH PSW
PUSH 03H
PUSH 04H
PUSH 05H
PUSH 06H
PUSH 07H
MOV R5,A
MOV A,B
JZ DIVIDE1
MOV R4,B
MOV A,R6
MOV R7,A
LCALL D457 ;调双字节除以单字节除法
MOV A,R3
SJMP DIVIDE2
DIVIDE1:
MOV B,R6
MOV A,R5
DIV AB
DIVIDE2:
POP 07H
POP 06H
POP 05H
POP 04H
POP 03H
POP PSW
RET
;***********************************************************
;双字节二进制无符号数除以单字节二进制数 CALL BY DIVIDE
;入口条件:被除数在R4(高字节)、R5(低字节)中,除数在R7中。
;出口信息:OV=0 时,单字节商在R3中,OV=1 时溢出。
;影响资源:PSW、A、R3~R7 堆栈需求: 2字节
;***********************************************************
D457:
CLR C
MOV A,R4
SUBB A,R7
JC DV50
SETB OV ;商溢出
RET
DV50:
MOV R6,#8 ;求平均值(R4R5/R7-→R3)
DV51:
MOV A,R5
RLC A
MOV R5,A
MOV A,R4
RLC A
MOV R4,A
MOV F0,C
CLR C
SUBB A,R7
ANL C,/F0
JC DV52
MOV R4,A
DV52:
CPL C
MOV A,R3
RLC A
MOV R3,A
DJNZ R6,DV51
MOV A,R4 ;四舍五入
ADD A,R4
JC DV53
SUBB A,R7
JC DV54
DV53:
INC R3
DV54:
CLR OV
RET
;******************************************************************
;KK与SEC中相应行相同列同步取元素子程序(SECKKP) CALL BY MATEE
;R2:为带入的行形参。R4:为带入的列形参。R5:带出SEC中的元素。A:带出KK中元素。
;该程序主要用于KK与SEC中任意行,相同列元素比较。
;******************************************************************
SECKBP:
CLR TR0
PUSH DPH
PUSH DPL
PUSH B
MOV DPTR,#SEC
MOV A,R2
MOV B,#DIMENVOL
MUL AB
ADD A,R4
JNC SECKBP1
INC B
SECKBP1:
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A
MOVX A,@DPTR
MOV R5,A
MOV DPTR,#KK
MOV A,R4
ADD A,DPL
MOV DPL,A
MOVX A,@DPTR
POP B
POP DPL
POP DPH
SETB TR0
RET
;********************************************************************
;销卡结帐子程序
;根据上位机发送的房间号和卡号,在SEC中找到相应向量的行号,删除该向量
;房间号从101开始,卡号为101-104
;如果卡号对应为FFH,则把该房间号对应的所有卡向量都删除
;带入参数:内部RAM 27H(ROOMID)和28H(CARDID)的内容,
;出口条件:匹配向量在SEC中的行号,由R2带出
;********************************************************************
DELIIC:
PUSH DPH
PUSH DPL
PUSH 02H
PUSH 03H
CLR TR0
MOV DPTR,#KEYQUA
MOVX A,@DPTR
JZ DELIIC3A
MOV R3,A ;R3为计数变量
MOV R2,#0 ;行号变量
DELIIC1:
MOV A,R2 ;定位待比较向量中的房间号基元
MOV B,#DIMENVOL
MUL AB
ADD A,#49
JNC DELIIC2
INC B
DELIIC2:
MOV DPTR,#SEC
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A
MOVX A,@DPTR
CJNE A,27H,DELIIC3 ;判房间号是否一致?
MOV A,28H
CJNE A,#00H,DELIIC2A
LCALL VECMOV
AJMP DELIIC4
DELIIC2A:
INC DPTR ;是,定位卡号基元,继续比较
MOVX A,@DPTR
CJNE A,28H,DELIIC3 ;判卡号是否一致?
LCALL VECMOV ;房间号,卡号都一致,即为待删向量
;R2作入口参数,调用删除模块
MOV SBUF,#0FCH
JNB TI,$
CLR TI
MOV A,R3
DEC A
JNZ DELIIC4
; MOV SBUF,#0FCH
; JNB TI,$
; CLR TI
AJMP DELEND
; AJMP DELIIC4
DELIIC3:
CJNE R3,#01,DELIIC3B
DELIIC3A:
; MOV A,#0FDH
MOV SBUF,#0FDH
JNB TI,$
CLR TI
AJMP DELEND
DELIIC3B:
INC R2
DELIIC4:
DJNZ R3,DELIIC1
DELEND:
POP 03H
POP 02H
POP DPL
POP DPH
RET
;***************************************************
;刷新48维特征子程序 CALL BY SECADMIN
;带入参数:R2,匹配向量在SEC中的行号
;***************************************************
REFRESH:
MOV R4,#0
REFRESH1:
MOV DPTR,#KK ;定位源地址
MOV A,DPL
ADD A,R4
MOV DPL,A
MOVX A,@DPTR
PUSH ACC
MOV A,R2
MOV B,#DIMENVOL
MUL AB
ADD A,R4
JNC REFRESH2
INC B
REFRESH2:
MOV DPTR,#SEC ;定位目的地址
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A
POP ACC
MOVX @DPTR,A
LCALL WRDELAY
CJNE R4,#47,REFRESH3 ;判断48个特征基元都刷新完否?
POP DPL
POP DPH
RET
REFRESH3:
INC R4
SJMP REFRESH1
;**************************************************
;向量移位子程序 CALL BY SECADMIN
;根据匹配行号,将其后的向量向前移动一个位置,
;覆盖该向量,达到删除的目的
;入口参数:R2,为待删除的向量在SEC中的行号
;出口参数:无
;**************************************************
VECMOV:
PUSH DPH
PUSH DPL
PUSH 03H
PUSH 04H
MOV DPTR,#KEYQUA ;确定需移动多少个向量,R3作为计数变量
MOVX A,@DPTR
CLR C
SUBB A,R2
DEC A
JZ VECMOV3
MOV R3,A
MOV R4,#DIMENVOL ;向量中元素移动的数目
MOV DPTR,#SEC
MOV A,R2 ;取行号
INC A ;到其下一行
MOV B,#DIMENVOL ;给定60维向量的所占字节数
MUL AB
ADD A,DPL ;定位匹配向量的后一个向量的首地址
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A
VECMOV1:
MOVX A,@DPTR ;读出源地址单元内容
PUSH DPH ;源地址暂存堆栈
PUSH DPL
PUSH ACC ;数据暂存堆栈
MOV A,DPL ;定位目的地址,与源地址相隔DIMENVOL个单元
CLR C
SUBB A,#DIMENVOL
JNC VECMOV2
DEC DPH
VECMOV2:
MOV DPL,A
POP A ;将数据写入目的地址单元
MOVX @DPTR,A
LCALL WRDELAY
POP DPL ;恢复源地址
POP DPH
INC DPTR ;源地址加1
DJNZ R4,VECMOV1 ;判一个向量内移动完成否?
DJNZ R3,VECMOV1 ;判待移动向量都完成否?
;修改KEYQUA减1
VECMOV3:
MOV DPTR,#KEYQUA
MOVX A,@DPTR
DEC A
MOVX @DPTR,A
LCALL WRDELAY
POP 04H
POP 03H
POP DPL
POP DPH
RET
;*************************************************************
;开锁模块程序(OPENLOCK)
;开锁模块用于嵌入多种锁头驱动模块程序,嵌入分支为B树结构。
;本系统设置8条分支,现已开发两种驱动模块。分支编号来源于H.参数。
;带入参数:匹配成功向量行号R2
;带出参数:无
;*************************************************************
OPENLOCK: CLR TR0
MOV A,R2 ;定位正确向量中的锁舌驱动方式基元
MOV B,#DIMENVOL
MUL AB
ADD A,#56
JNC OPENLOCK0
INC B
OPENLOCK0:
MOV DPTR,#SEC
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A
MOVX A,@DPTR ;获得锁舌驱动方式
JZ OPENKEY1
DEC A
JZ OPENKEY2
OPENKEY1: LCALL MOTSTE ;如果H.=0
SJMP OPENKEYEND
OPENKEY2: LCALL ELESWI ;如果H.=1
;LCALL MOTSTE ;如果H.=2
;SJMP OPENKEY2
;LCALL MOTSTE ;如果H.=3
;SJMP OPENKEY2
;LCALL MOTSTE ;如果H.=4
;SJMP OPENKEY2
;LCALL MOTSTE ;如果H.=5
;SJMP OPENKEY2
;LCALL MOTSTE ;如果H.=6
;SJMP OPENKEY2
;LCALL MOTSTE ;如果H.=7
OPENKEYEND: SETB TR0
RET
;***********************************************************
;步进电机驱动模块程序(MOTSTE)
;步进电机的驱动原理和锁舌长度学习子程相同。两个模块的重要
;不同之处是当锁舌到达开门位置时不是立即返程,而是维持由用户指定的时间,
;维持时间到后锁舌返程。本模块的基本符号及用途与锁舌长度学习子程相同。
;特殊符号为CTOFLAG,即定时器延时性质的控制信号,CTOFLAG = 0,
;表示定时器为正常的复位延时;反之位锁头延时
;带入参数:匹配成功向量的行号R2
;带出参数:无
;***********************************************************
MOTSTE:
CLR MF
PUSH 00H
MOV A,R2
MOV B,#DIMENVOL
MUL AB
ADD A,#49
JNC MOTSTE1
INC B
MOTSTE1:
MOV DPTR,#SEC
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A
MOVX A,@DPTR ;定位到房间号基元KH,
DEC A
MOV B,A ;获得房间号暂存入B
INC DPTR
INC DPTR
INC DPTR
INC DPTR
INC DPTR
INC DPTR ;定位到开门维持时间
MOTSTE2: MOVX A,@DPTR
MOV CT0,A ;获得开门维持时间
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -