⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdm_key.asm

📁 这是一个电子锁软件,希望对大家有好帮助 这是一个电子锁软件,希望对大家有好帮助
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;
; ┏━━━━━━━━━━━━━┓
; ┃┏━━━━━━━━━━━┓┃
; ┃┃防盗门IC卡按键控制板  ┃┃
; ┃┃	     源	程 序	    ┃┃
; ┃┃	     HT48R06A	    ┃┃
; ┃┃	 V1.0  2005.12.07   ┃┃
; ┃┗━━━━━━━━━━━┛┃
; ┗━━━━━━━━━━━━━┛
#include HT48R06A-1.inc			;定义HT48R05A寄存器地址
;
;-------------------------------------------------------------------------
FUNC		.SECTION 'DATA'		;== 功能寄存器RAM节区 ==
;-------------------------------------------------------------------------
;********************
;* 数据表及参数定义 *
;********************
;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
ALM_SET1	EQU	02		;报警蜂鸣每遍次数                    				 ┃
ALM_SET2	EQU	03		;报警蜂鸣遍数                    				     ┃
ALM_TIM_SET	EQU	01		;每遍间隔时间(1x1s=1s)         				     ┃
ALM_KEY_SET	EQU	02		;键入出错次数预置(实际3次)         				     ┃
ALM_KEY_ES_SET	EQU	15		;键入出错超次延时预置(超过后封键15s) 			 ┃
MD_ON_SET	EQU	50		;马达开启定时时间(50x10ms=0.5s)   				     ┃
MD_OFF_SET	EQU	10		;马达关闭定时时间(10x1s=10s)        				 ┃
HALT_SET	EQU	60		;冬眠前定时设置(x1秒)                				 ┃
HALT_LOW_SET	EQU	240		;欠压报警冬眠前定时设置(x1秒)     			     ┃
BAT_LOW_SET	EQU	05              ;低电压报警定时设置(x1秒)            		 ┃
;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
;**************
;* 输出口定义 *

;**************
ROW3		EQU	PB.0		;键扫描列线3(出口)
ROW2		EQU	PB.1		;键扫描列线2(出口)
ROW1		EQU	PB.2		;键扫描列线1(出口)
;
MD_FZ		EQU	PA.4		;马达反转控制线
MD_ZZ		EQU	PA.5		;马达正转控制线
;
SDA			EQU	PA.6		;定义PA.6为数据脚
SDA_C		EQU	PAC.6		;定义PA.6的控制方向
SCL			EQU	PA.7		;定义PA.7为时钟脚
SCL_C		EQU	PAC.7		;定义PA.7的控制方向
;
FM			EQU	PC.1		;蜂鸣器控制线
;
;**************
;* 输入口定义 *
;**************
COL1		EQU	PA.0		;键扫描行线1
COL2		EQU	PA.1		;键扫描行线2
COL3		EQU	PA.2		;键扫描行线3
COL4		EQU	PA.3		;键扫描行线4
;
MODI_KEY	EQU	PA.7		;PA.7作输入时改码允许键
;
BAT_LOW		EQU	PC.0		;低电压测试线
;
;
;****************
;* 内存单元定义	*
;****************
KEY_DAT		DB	6 DUP(?)	;定义6位键入码变量数组(6字节)
TEST_DAT	DB	6 DUP(?)
;
KEY_CNT		DB	?		;按键次数计数器
KEY_DAT_BUF	DB	?		;键码暂存器
OPEN_KEY_CNT	DB	?		;【#】键计数器
MD_ON_CNT	DB	?		;马达开启定时计数器
MD_OFF_CNT	DB	?		;马达关闭定时计数器
;
TMPE1		DB	?		;中断时累加器A暂存单元
;
US10_CNT	DB	?		;10ms计数器
T_20MS		DB	?		;20ms计数器
MST_CNT		DB	?		;秒计数器
;
FM_TIM		DB	?		;蜂鸣定时计数器
FM_CNT		DB	?		;蜂鸣次数计数器
FM_OSC		DB	?		;蜂鸣振荡计数器
ALM_TIM		DB	?		;报警蜂鸣间隔定时
ALM_CNT		DB	?		;报警蜂鸣次数计数器
ALM_KEY_CNT	DB	?		;键入出错计数器
ALM_KEY_TIM	DB	?		;键入出错超次延时计数器
;
LINE		DB	?		;键值暂存器
LINE1		DB	?		;第一行键值寄存器
LINE2		DB	?		;第二行键值寄存器
LINE3		DB	?		;第三行键值寄存器
;
READ_OUT	DB	?		;读出数据暂存器
WRITE_IN	DB	?		;写入数据暂存器
WORD_ADDR	DB	?		;读写地址暂存器
DATA_8		DB	?		;传送数据位长度计数器
WRITE_ES	DB	?		;写入延时计数器
BYTE_DAT	DB	?		;待写内容暂存器
BYTE_W_CNT	DB	?		;写入字节计数器
BYTE_R_CNT	DB	?		;读出字节计数器
W_ADDR_SET	DB	?		;待写地址指针
R_ADDR_SET	DB	?		;待读地址指针
;
HALT_TIM	DB	?		;进入冬眠前定时计数器
BAT_LOW_TIM	DB	?		;低电压报警定时计数器	
;
;**************
;* 标志位定义 *
;**************
FM_ON		DBIT			;开蜂鸣延时标志
FM_OFF		DBIT			;关蜂鸣延时标志
BEE		DBIT			;蜂鸣允许标志
;
KEY_CL_EN	DBIT			;键处理允许标志
OPEN_EN		DBIT			;开门允许标志
;
MD_ZZ_ON_ES	DBIT			;马达正转开启定时标志
MD_FZ_ON_ES	DBIT			;马达反转开启定时标志
MD_ZZ_OFF_ES	DBIT			;马达正转关闭定时标志
;
ALM_EN		DBIT			;报警允许标志
ALM_LOP		DBIT			;报警循环标志
ALM_TIM_EN	DBIT			;报警间隔定时允许标志
ALM_KEY_EN	DBIT			;键入出错超次延时允许标志
ALM_DOWN	DBIT			;欠次开门出错标志
ALM_LOW_EN	DBIT			;低电压报警允许标志
;
WRITE_ES_EN	DBIT			;写入延时允许标志
MODI_EN		DBIT			;改码允许键已按过标志
WRITE_EN0	DBIT			;写码允许标志0(已输入2次"#"键)
WRITE_EN1	DBIT			;写码允许标志1(已输入"8"键)
WRITE_EN2	DBIT			;写码允许标志2(已输入"*"键)
WRITE_EN3	DBIT			;写码允许标志3(已输入6位新码)
KEY_6_OK	DBIT			;6次数字键已输入标志
MODI_FM_EN	DBIT			;改码键蜂鸣允许标志
;
HALT_TIM_EN	DBIT			;冬眠定时允许标志
HALT_EN		DBIT			;冬眠允许标志
PD_FLG		DBIT			;冬眠进入标志
;
BAT_LOW_ES	DBIT			;低电压报警延时标志
;------------------------------------------------------------------------
PROG		.SECTION AT 0 'CODE'	;== 程序ROM节区	== (从"000H"开始存放)
;------------------------------------------------------------------------
		ORG	000H
		JMP	CSH		;转初始化程序
;
		ORG	008H
		JMP	TI0		;定时中断0地址
;
;*****************************
;* ◆内部RAM(40H~7FH)清零◆ *
;*****************************
CSH:		
		MOV	A,ALM_KEY_ES_SET;取出超次延时预置数
		MOV	ALM_KEY_TIM,A	;设置超次延时计数器
;
		SZ	ALM_KEY_EN	;检查超次延时允许标志	
		JMP	CSH2		;是超次延时后按的复位键,则先延时,后初始化
;
		MOV	A,40H		;设置RAM起始地址(48R06A为40H~7FH)
		MOV	MP,A		;设置间址指针MP
		MOV	A,40H		;设置清"0"字节数(64字节)
CSH1:		CLR	[00H]		;内存清"0"
		INC	MP		;间址指针MP加一
		SDZ	ACC
		JMP	CSH1		;A≠"00",转CSH1循环
;********************************
;* ◆定时中断初始化◆		*
;* TMRC.7←"1" TM1		*
;* TMRC.6←"0",TM0 内部定时模式	*
;* TMRC.5←"0",未定义		*
;* TMRC.4←"0",TON 禁止计数	*
;* TMRC.3←"0",TE 脉冲前沿触发	*
;* TMRC.2←"0" PSC2 fin=1/4fsys	*
;* TMRC.1←"1" PSC1		*
;* TMRC.0←"0" PSC0		*
;********************************
CSH2:		MOV	A,10100001B	;TM1,TM0=10,定时模式.PSC=001,系统时钟4分频
		MOV	TMRC,A		;TON=0,禁止定时.TE=0,前沿触发
;
		MOV	A,38H		;100H-38H=c8H(200D),1μsX200=200μs
		MOV	TMR,A		;TR设置200μs定时初值
;
		SET	EMI		;EMI←"1",打开总中断控制位
		SET	ETI		;ETI←"1",允许定时中断
		SET	TMRC.4		;TON←"1",允许定时器计数
;
;***********************
;* ◆I/O口初始化设置◆ *
;***********************
		SET	PAC.0		;PA.0定义为输入口
		SET	PAC.1		;PA.1定义为输入口
		SET	PAC.2		;PA.2定义为输入口
		SET	PAC.3		;PA.3定义为输入口
;
		CLR	PAC.4		;PA.4定义为输出口
		CLR	PAC.5		;PA.5定义为输出口
		CLR	PAC.6		;PA.6定义为输入口
		CLR	PAC.7		;PA.7定义为输出口
;
		CLR	PBC.0		;PB.0定义为输出口
		CLR	PBC.1		;PB.1定义为输出口
		CLR	PBC.2		;PB.2定义为输出口
;
		SET	PCC.0		;PC.0定义为输出口
		CLR	PCC.1		;PC.1定义为输出口
;
		MOV	A,02		;蜂鸣计数器初始赋值
		MOV	FM_CNT,A
		SET	BEE			;蜂鸣一次允许
;
		MOV	A,25		;预置写入延时计数器
		MOV	WRITE_ES,A
;
		CLR	SCL_C		;定义时钟脚为输出口
		CLR	WRITE_ES_EN
;
		MOV	A,02
		MOV	T_20MS,A	;重置20MS计数器(2x10ms=20ms)
;
		MOV	A,MD_ON_SET	;预置马达开启定时常数
		MOV	MD_ON_CNT,A
		MOV	A,MD_OFF_SET	;预置马达关闭定时常数
		MOV	MD_OFF_CNT,A
;
		MOV	A,10H			;预设EEPROM存放地址
		MOV	R_ADDR_SET,A	;预置待读地址指针
		MOV	W_ADDR_SET,A	;预置待写地址指针
;		
		MOV	A,ALM_KEY_SET	;取出键入出错预置数
		MOV	ALM_KEY_CNT,A	;重置键入出错计数器		
;
		SET	HALT_TIM_EN	;冬眠定时允许标志置位
		MOV	A,HALT_SET	;重置1分钟冬眠定时
		MOV	HALT_TIM,A
;******************************
;* 若为欠压状态,则延长到250秒 *
;******************************
		SNZ	ALM_LOW_EN	;检查低电压报警允许标志
		JMP	MAIN9		;="0",冬眠延时60秒
		MOV	A,HALT_LOW_SET	;重置250秒冬眠定时
		MOV	HALT_TIM,A
;
MAIN9:	
		SNZ	PDF		;检查是否为冬眠后进入(PDF在HALT后置"1")
		JMP	MAIN		;PDF="0",是上电后进入
		SET	PD_FLG		;冬眠进入标志置位
		CLR	WDT		;清冬眠标志,DF←"0"
;
		SET	BAT_LOW		;PC.0←"1",低电压测试线准备输入		;
		SET	FM		;PC.1←"1",关蜂鸣驱动
;
;●●●●●●
;● 主程序 ●
;●●●●●●
MAIN:
;*********************************
;* 开启应答     短鸣2次          *
;* 改码键应答   短鸣3次          *
;* 开锁应答     短鸣4次          *
;* 存入新码应答 短鸣6次          *
;* 超次报警     长鸣2次循环3遍   *
;* 欠次报警     长鸣1次循环3遍   *
;* 低压报警     短鸣1次延时5秒   *
;*********************************
;
;********************
;* 检查低电压检测线 *	
;********************
		SZ	BAT_LOW		;检查低电压检测线
		JMP	MAIN6		;BAT_LOW="1"电压正常,转MAIN6继续
		SET	ALM_LOW_EN	;低电压报警允许标志置位
;*******************************
;* BAT_LOW="0",低电压报警处理 *
;*******************************
		SZ	BAT_LOW_ES	;检查低电压报警延时标志
		JMP	MAIN7		;正在低电压报警延时,转MAIN7继续
		SET	BAT_LOW_ES	;低电压报警延时标志置位
		MOV	A,BAT_LOW_SET
		MOV	BAT_LOW_TIM,A	;预置低电压报警定时常数
		MOV	A,01		;短叫1吹(每隔5秒叫一次)
		MOV	FM_CNT,A
		SET	BEE		;蜂鸣一次允许
		JMP	MAIN7
;
MAIN6:		CLR	ALM_LOW_EN	;低电压报警允许标志复位
;******************
;* 检查改码允许键 *
;******************
MAIN7:	
		SZ	OPEN_EN		;检查开门状态
		JMP	MAIN3		;锁舌尚未返回,禁止改码(需等侍10秒钟)
		SZ	WRITE_EN3	;检查写码允许标志2
		JMP	MAIN3		;正在写码,PA.7忙,禁止读键值,转MAIN3出去
		SET	PAC.7		;定义PA.7为输入口
		SET	PA.7		;预置"1",准备接收数据(作输入/输出时必须有)
		NOP			;延时2μs,确保PA.7置"1",否则读出为"0",出错!
		NOP
		SZ	MODI_KEY	;检查改码键有无按下("MODI_KEY"=PA.7)
		JMP	MAIN2
		SET	MODI_EN		;改码允许键已按过标志置位
		SZ	MODI_FM_EN	;检查蜂鸣允许标志
		JMP	MAIN4		;键未放,但已叫过,转MAIN4恢复输出口继续
		MOV	A,03		;改码允许键应答,叫3次
		MOV	FM_CNT,A
		SET	BEE			;蜂鸣一次
		SET	MODI_FM_EN	;蜂鸣允许标志置位
MAIN4:	
		CLR	SCL_C		;恢复PA.7为输出口,定义时钟脚为输出口
		JMP	MAIN3
;
MAIN2:		
		CLR	MODI_FM_EN	;蜂鸣允许标志置位
		CLR	SCL_C		;恢复PA.7为输出口,定义时钟脚为输出口
;	
;**************
;* 键入码处理 *
;**************
MAIN3:		
		SZ	MD_FZ_ON_ES	;检查马达反转开启定时标志
		JMP	MD_FZ_ON	;正在延时,转MD_FZ_ON等待
;
		SZ	MD_ZZ_OFF_ES	;检查马达正转关闭定时标志
		JMP	MD_ZZ_OFF	;正在延时,转MD_ZZ_OFF等待
;
		SZ	MD_ZZ_ON_ES	;检查马达正转开启定时标志
		JMP	MD_ZZ_ON	;正在延时,转MD_ZZ_ON等待
;		
		SNZ	KEY_6_OK	;检查6位数码是否送齐
		JMP	KRCL_CHK1	;不足6位,禁止写码处理
;*************************
;* 检查是否为新6位码键入 *
;*************************		
		SNZ	WRITE_EN2	;检查写码允许2标志
		JMP	KRCL_CHK	;="0",是开门键入码,禁止写新码
		SET	WRITE_EN3	;写码允许3标志置位(已输入6位新码)
		JMP	EEPROM_WRITE	;转写码程序
;
KRCL_CHK1:	
		SNZ	KEY_CL_EN	;检查键码处理允许标志(1~6次数字键有效)
		JMP	KRCL_CHK	;="0",转KRCL_CHK,禁止键码处理
;********************
;* 键入码送数组处理 *
;********************
		CLR	KEY_CL_EN	;键入码处理允许标志复位
		MOV	A,KEY_CNT	;取出键入次数计数器值
		DEC	ACC			;从KEY_DAT[0]开始存数据
		ADD	A,OFFSET KEY_DAT;迭加6位内码变量数组指针
		MOV	MP,A		;设置当前键入码数组指针(48R05没有MP0,MP1)
		MOV	A,KEY_DAT_BUF	;读出当前键入码数据
		MOV	IAR,A		;存入当前键入码数组("IAR"=Old"R0")
		MOV	A,06
		XOR	A,KEY_CNT	;检查键入次数计数器值是否为6次
		SZ	ACC
		JMP	KRCL1		;≠"06",转KRCL1加一
;*******************
;* 6位码已键入完整 *
;*******************
		CLR	KEY_CNT		;="06",键入次数计数器清"0"
		SET	KEY_6_OK	;6次数字键已送完标志置位
;		
KRCL_CHK:	
		SNZ	OPEN_EN		;检查开门允许标志
		JMP	KRCL_END	;="0",禁止开门
;**************
;* 允许开门了 *
;**************
		CLR	KEY_6_OK
;		CLR	OPEN_EN		;开门允许标志复位
;
;*********************
;* 校验6位码是否正确 *
;*********************
		MOV	A,OFFSET KEY_DAT;取出6位键入码数组首址
		MOV	MP,A		;设置当前键入码数组指针(48R0只有MP)
;
		MOV	A,06
		MOV	BYTE_R_CNT,A	;预置6位读出字节计数器
;
		MOV	A,R_ADDR_SET	;取出待读6位密码地址指针
		MOV	WORD_ADDR,A	;设置写入操作码地址首址
;
READ1:		
		CALL	STRT		;调用发送起始信号子程序
		MOV	A,0A0H		;写入控制字节(A0H为写模式)
		CALL	WBYTE		;调用字节写入子程序
		MOV	A,WORD_ADDR	;写入地址字节
		CALL	WBYTE		;调用字节写入子程序
		CALL	STRT		;调用发送起始信号子程序
		MOV	A,0A1H		;写入控制字节(A1H为读模式)
		CALL	WBYTE		;调用字节写入子程序
		CALL	RBYTE		;调用字节读出子程序
		CALL	STOP		;调用发送停止信号子程序
;
		MOV	A,IAR		;取出当前地址6位键入码数组内容(R0)
		XOR	A,READ_OUT	;与对应地址密码比较
		SZ	ACC
		JMP	FAIL_OUT	;出错,转FAIL_OUT处理
;******************
;* 当前位校验通过 *
;******************
		INC	WORD_ADDR	;EEPROM地址加一
		INC	MP		;键入码数组指针加一
		SDZ	BYTE_R_CNT	;读出字节计数器减一
		JMP	READ1		;6位未满,转READ1循环
;****************************
;* 6位密码校验全部通过,开锁 *
;****************************
		MOV	A,04		;叫4次,校验正确应答
		MOV	FM_CNT,A
;
		SET	MD_FZ		;关闭马达反转控制
		CLR	MD_ZZ		;开启马达正转控制
		SET	MD_ZZ_ON_ES	;马达正转开启定时标志置位
		MOV	A,MD_ON_SET	;预置马达开启定时常数
		MOV	MD_ON_CNT,A	;(正转开启)
;
MD_ZZ_ON:	SZ	MD_ON_CNT	;检查马达开启定时计数器
		JMP	KRCL_END	;开定时未到,出去
;******************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -