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

📄 fdm_key.asm

📁 这是一个电子锁软件,希望对大家有好帮助 这是一个电子锁软件,希望对大家有好帮助
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;* 正转开启定时到 *
;******************
		MOV	A,MD_OFF_SET	;重置马达关闭定时常数
		MOV	MD_OFF_CNT,A
		SET	MD_ZZ		;关闭马达正转控制
		SET	MD_FZ		;关闭马达反转控制
		SET	MD_ZZ_OFF_ES	;马达关闭定时标志置位
;
MD_ZZ_OFF:	SZ	MD_OFF_CNT	;检查马达关闭定时计数器
		JMP	KRCL_END	;关定时未到,出去
;******************
;* 正转关闭定时到 *
;******************
		MOV	A,MD_ON_SET	;预置马达开启定时常数
		MOV	MD_ON_CNT,A	;反转开启,(正,反转的开启定时是一样的)
		SET	MD_ZZ		;关闭马达正转控制
		CLR	MD_FZ		;开启马达反转控制
		SET	MD_FZ_ON_ES	;马达反转开启定时标志置位
;
MD_FZ_ON:	SZ	MD_ON_CNT	;检查马达开启定时计数器
		JMP	KRCL_END	;开定时未到,出去
;******************
;* 反转开启定时到 *
;******************
		SET	MD_ZZ		;关闭马达正转控制
		SET	MD_FZ		;关闭马达反转控制
;
		CLR	MD_ZZ_ON_ES	;马达正转开启定时标志复位
		CLR	MD_ZZ_OFF_ES	;马达关闭定时标志复位
		CLR	MD_FZ_ON_ES	;马达反转开启定时标志复位
;
		CLR	WRITE_EN0	;写码允许标志复位
		CLR	OPEN_EN		;开门允许标志复位
;****************
;* 恢复改码标志 *
;****************
		CLR	KEY_CNT		;键入次数计数器清"0"
		CLR	MODI_EN		;改码键标志复位
		CLR	OPEN_KEY_CNT	;【#】键计数器清"0"
;****************
;* 恢复超次标志 *
;****************
		CLR	ALM_KEY_EN	;超次延时允许标志复位		
		MOV	A,ALM_KEY_SET	;取出键入出错预置数
		MOV	ALM_KEY_CNT,A	;重置键入出错计数器
;
KRCL_END:	JMP	EEPROM_WRITE	;键入码处理结束,转EEPROM_WRITE继续
;
;****************************
;* 6位码尚未键入完整,不校验 *
;****************************
KRCL1:		
		JMP	EEPROM_WRITE	;键入码处理结束,转EEPROM_WRITE继续
;
;************
;* 出错处理 *
;************
FAIL_OUT:	SZ	ALM_KEY_CNT	;检查键入出错计数器
		JMP	FAIL_OUT1	;次数未到,转FAIL_OUT1继续
;*****************
;* 键入出错满3次 *
;*****************
		MOV	A,ALM_KEY_SET	;取出键入出错预置数
		MOV	ALM_KEY_CNT,A	;重置键入出错计数器
;
		SET	ALM_KEY_EN	;超次延时允许标志置位		
;
		MOV	A,ALM_KEY_ES_SET;取出超次延时预置数
		MOV	ALM_KEY_TIM,A	;设置超次延时计数器
		JMP	FAIL_OUT2		
;		
FAIL_OUT1:	DEC	ALM_KEY_CNT	;键入出错计数器减1
;
FAIL_OUT2:	SET	ALM_EN		;报警允许标志置位
		CLR	OPEN_EN		;开门允许标志复位
		CLR	KEY_CNT		;键入次数计数器清"0"
		CLR	MODI_EN		;改码键标志复位
		CLR	OPEN_KEY_CNT	;【#】键计数器清"0"
		JMP	WRITE_END	;键入码处理结束,转EEPROM_WRITE继续
;
;**********************************
;* EEPROM写入程序		  *
;* 入口: KEY_DAT   ←写入数据	  *
;*	 W_ADDR_SET←读写地址指针 *
;**********************************
EEPROM_WRITE:	
		SNZ	WRITE_EN3	;检查写码允许标志2
		JMP	WRITE_END	;禁止写码,转WRITE_END出去
;
		SZ	WRITE_ES_EN	;检查写入延时允许标志
		JMP	ES_5MS		;正在写入延时,转ES_5MS等待
;
		MOV	A,06
		MOV	BYTE_W_CNT,A	;预置6位写入字节计数器
;
		MOV	A,OFFSET KEY_DAT;设置6位键入码数组指针
		MOV	MP,A		;备份MP
;
		MOV	A,W_ADDR_SET	;取出待写地址指针
		MOV	WORD_ADDR,A	;设置写入地址首址
;
WRITE1:			
		MOV	A,IAR		;取出当前地址数据(R0)
		MOV	WRITE_IN,A	;存入待写字节寄存器
		CALL	STRT		;调用发送起始信号子程序
		MOV	A,0A0H		;写入控制字节(A0H为写模式)
		CALL	WBYTE		;调用字节写入子程序
		MOV	A,WORD_ADDR	;写入地址字节
		CALL	WBYTE		;调用字节写入子程序
		MOV	A,WRITE_IN	;写入数据字节
		CALL	WBYTE_NO	;调用字节写入子程序(无应答位)
		CALL	STOP		;调用发送停止信号子程序
;
		SET	WRITE_ES_EN	;写入延时允许标志置位
ES_5MS:		SZ	WRITE_ES	;检查写入延时计数器
		JMP	WRITE_END
		MOV	A,25		;重置写入延时计数器
		MOV	WRITE_ES,A	;25x200μs=5ms
		CLR	WRITE_ES_EN	;写入延时允许标志复位
;
		INC	MP		;待写数组地址加一
		INC	WORD_ADDR	;EEPROM地址加一
		SDZ	BYTE_W_CNT	;写入字节计数器减一
		JMP	WRITE1		;≠"0",转WRITE1循环
;
		MOV	A,06		;叫6次,写码应答
		MOV	FM_CNT,A
;
		CLR	WRITE_EN0	;写码允许标志复位
		CLR	WRITE_EN1	;写码允许标志复位
		CLR	WRITE_EN2	;写码允许标志复位
;		CLR	WRITE_EN3	;写码允许标志复位
		CLR	KEY_6_OK	;6位数码标志复位
		CLR	MODI_EN		;改码键标志复位
		CLR	OPEN_KEY_CNT	;【#】键计数器清"0"
		CLR	KEY_CNT		;="06",键入次数计数器清"0"
;
;**************************
;* 写入内容读出检查(TEST) *
;**************************
;		MOV	A,OFFSET TEST_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	;设置写入操作码地址首址
;READ11:	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	IAR,A		;当前EEPROM地址内容送TEST数组(R0)
;
;		INC	WORD_ADDR	;EEPROM地址加一
;		INC	MP		;键入码数组指针加一
;		SDZ	BYTE_R_CNT	;读出字节计数器减一
;		JMP	READ11		;6位未满,转READ1循环
;
		CLR	WRITE_EN3	;写码允许标志复位
;
WRITE_END:
		JMP	MAIN1		;EEPROM写入程序结束,转MAIN1继续
;
MAIN1:		CALL	BEEP		;调用蜂鸣子程序
;
;●●●●●●●●●●●●●●●
;● 主程序结束,	返回MAIN循环 ●
;●●●●●●●●●●●●●●●
		SNZ	HALT_EN		;检查冬眠允许标志
		JMP	MAIN		;返回主程序入口处
		CLR	HALT_EN		;冬眠允许标志复位
;****************************************
;* HALT_EN="1"冬眠允许,冬眠前先关闭LCD *
;****************************************
		SET	PA.0		;PA.0←"1"
		SET	PA.1		;PA.1←"1"
		SET	PA.2		;PA.2←"1"
		SET	PA.3		;PA.3←"1"

		SET	PA.4		;PA.4←"1"
		SET	PA.5		;PA.5←"1"
		SET	PA.7		;PA.7←"1"
		SET	PA.6
;
		CLR	PBC.0
		CLR	PBC.1
		CLR	PBC.2
		SET	PB.0		;PB.0←"1"
		SET	PB.1		;PB.1←"1"
		SET	PB.2		;PB.2←"1"
;
;/////////////////////////
		HALT			;进入冬眠
;/////////////////////////
;****************
;* 冬眠唤醒处理	*
;****************
		JMP	CSH		;冬眠唤醒后直接转初始化,从头开始执行
;///////////////////////////
;
;*******************************
;* ◆200us时标T0定时中断处理◆ *
;*******************************
TI0:		
		MOV	TMPE1,A		;ACC进栈
;
		MOV	A,38H		;100H-38H=c8H(200D),1μsX200=200μs
		MOV	TMR,A		;TR设置200μs定时初值
;
;**************************
;* ◆检查蜂鸣振荡计数器◆ *
;**************************
		SNZ	FM_ON		;检查开蜂鸣延时标志
		JMP	TI2		;正在开蜂鸣延时,转TI2继续
;
		SDZ	FM_OSC		;检查蜂鸣振荡定时,200μs
		JMP	TI2
;
		MOV	A,01		;01x200μs=200μs→2500Hz
		MOV	FM_OSC,A	;重置蜂鸣振荡定时计数器
;		
		SZ	FM		;检查蜂鸣控制线状态
		JMP	TI1		;是"1",转TI1清"0"
		SET	FM		;蜂鸣器控制线置"1",关蜂鸣
		JMP	TI2		;转TI2继续
;
TI1:		CLR	FM		;蜂鸣器控制线置"0",开蜂鸣
;
;********************************
;* ◆EEPROM写入延时计数器处理◆	*
;********************************
TI2:		SZ	WRITE_ES_EN	;检查写入延时允许标志
		DEC	WRITE_ES	;="1",写入延时计数器减一
;
;**************************
;* ◆10ms定时计数器处理◆ *
;**************************
		SDZ	US10_CNT	;10ms计数器减1
		JMP	TIO_END		;不为"0"出定时中断
		MOV	A,50		;50x200us=10ms
		MOV	US10_CNT,A	;重置10ms计数器
;
;*******************************
;* ◆10ms定时到,马达开启定时◆ *
;*******************************
		SNZ	MD_ZZ_ON_ES	;检查马达正转开启定时标志
		JMP	TI_FM		;禁止正转延时,转TI_FM等待
		SZ	MD_ON_CNT	;检查马达开启定时计数器
		DEC	MD_ON_CNT	;不为"0",定时器减一
;
;***************************
;* ◆10ms定时到,蜂鸣定时◆ *
;***************************
TI_FM:		
		SZ	FM_TIM		;检查蜂鸣定时器
		DEC	FM_TIM		;不为"0",定时器减一
;
;****************************
;* ◆检查键消抖20ms定时器◆ *
;****************************
		SDZ	T_20MS		;检查20ms计数器
		JMP	KSERV_END	;20ms未到,转KSERV_END出口
		MOV	A,02
		MOV	T_20MS,A	;重置20MS计数器(2x10ms=20ms)
;
;******************************************
;* 键扫描	  PA.0	PA.1  PA.2  PA.3  *
;*		  列 1	列 2  列 3  列 4  *
;*		  COL1	COL2  COL3  COL4  *
;*----------------------------------------*
;* PB.2	行一 ROW1【1】【4】【7】【*】 *
;*----------------------------------------*
;* PB.1	行二 ROW2【2】【5】【8】【0】 *
;*----------------------------------------*
;* PB.0	行三 ROW3【3】【6】【9】【#】 *
;******************************************
KEY:		SZ	ALM_KEY_EN	;检查键入出错超次延时标志
		JMP	TI3		;="1",正在键入出错超次延时,禁止键扫描
;		
		CLR	ROW1		;ROW1←"0",扫描第一行
		SET	ROW2		;ROW2←"1",第二行置高复位
		SET	ROW3		;ROW3←"1",第三行置高复位
		MOV	A,0FH		;A←00001111
		ORM	A,PA		;PA.0~PA.3←"1",准备读取键值
		NOP			;适当延时,保证读数正确,至少2拍
		NOP
		NOP
		NOP
		NOP
		NOP
		MOV	A,PA		;读取第一行键值
		MOV	LINE,A		;暂存键扫描第一行新键值
		XOR	A,LINE1		;新老键值异或,相同,则ACC="0"
		SZ	ACC		;检查有无按键?(检查有否与上一次相同?)
		JMP	KSERV1		;ACC≠"0",有按键,转KSERV1第一行键处理
;*******************************
;第一行无按键,则继续扫描第二行 *
;*******************************
		SET	ROW1		;ROW1←"1",第一行置高复位
		CLR	ROW2		;ROW2←"0",扫描第二行
		SET	ROW3		;ROW3←"1",第三行置高复位
		MOV	A,0FH		;A←00001111
		ORM	A,PA		;PA.0~PA.3←"1",准备读取键值
		NOP			;适当延时,保证读数正确,至少2拍
		NOP
		NOP
		NOP
		NOP
		NOP
		MOV	A,PA		;读取第二行键值
		MOV	LINE,A		;暂存键扫描第二行新键值
		XOR	A,LINE2		;新老键值异或,相同,则ACC="0"
		SZ	ACC		;检查有无按键?(检查有否与上一次相同?)
		JMP	KSERV2		;ACC≠"0",有按键,转KSERV2第二行键处理
;*******************************
;第二行无按键,则继续扫描第三行 *
;*******************************
		SET	ROW1		;ROW1←"1",第一行置高复位
		SET	ROW2		;ROW2←"1",第二行置高复位
		CLR	ROW3		;ROW3←"0",扫描第三行
		MOV	A,0FH		;A←00001111
		ORM	A,PA		;PA.0~PA.3←"1",准备读取键值
		NOP			;适当延时,保证读数正确,至少2拍
		NOP
		NOP
		NOP
		NOP
		NOP
		MOV	A,PA		;读取第三行键值
		MOV	LINE,A		;暂存键扫描第三行新键值
		XOR	A,LINE3		;新老键值异或,相同,则ACC="0"
		SZ	ACC		;检查有无按键?(检查有否与上一次相同?)
		JMP	KSERV3		;ACC≠"0",有按键,转KSERV3第三行键处理
KSERV_END:	SET	ROW3
		JMP	TI3		;键处理结束,转TI3继续
;
;********************************
;* 只有数字键才进行键入次数累计 *
;********************************
KSERV_END1:	SET	KEY_CL_EN	;键处理允许标志置位
		INC	KEY_CNT		;键入次数计数器加一
;************************************
;* 确保数码键后按【#】键是第一次按 *
;************************************
		CLR	OPEN_KEY_CNT	;【#】键计数器清"0"
;		
KSERV_END2:	SET	BEE		;蜂鸣一次,按键应答(仅【#】,【*】键用)
;***********************************
;* 有任意键按下即重置1分钟冬眠定时 *
;***********************************
		MOV	A,HALT_SET	;重置1分钟冬眠定时
		MOV	HALT_TIM,A
;******************************
;* 若为欠压状态,则延长到250秒 *
;******************************
		SNZ	ALM_LOW_EN	;检查低电压报警允许标志
		JMP	TI3		;="0",延时60秒
		MOV	A,HALT_LOW_SET	;重置250秒冬眠定时
		MOV	HALT_TIM,A
;
		JMP	TI3		;键处理结束,转TI3继续
;
;****************************
;* 第一行键值分析	    *
;*--------------------------*
;*  PA.0  PA.1	PA.2  PA.3  *
;*  COL1  COL2	COL3  COL4  *
;* ------------------------ *
;* 【1】【4】【7】【*】 *
;****************************
KSERV1:	
		MOV	A,LINE		;取出第一行新键值
		MOV	LINE1,A		;更新第一行键值寄存器
		SNZ	ACC.0		;检查COL1是否为"0"
		JMP	KEY_1		;是【1】键有按下,转KEY_1键处理
		SNZ	ACC.1		;检查COL2是否为"0"
		JMP	KEY_4		;是【4】键有按下,转KEY_4键处理
		SNZ	ACC.2		;检查COL3是否为"0"
		JMP	KEY_7		;是【7】键有按下,转KEY_7键处理
		JMP	KSERV_END	;无按键,转KSERV_END,键处理结束
;
;***************
;*【1】键处理 *
;***************
KEY_1:		MOV	A,01H
		MOV	KEY_DAT_BUF,A	;键码暂存器←"01H"
		JMP	KSERV_END1	;转KSERV_END1蜂鸣,继续
;
;***************
;*【4】键处理 *
;***************
KEY_4:		
		MOV	A,04H
		MOV	KEY_DAT_BUF,A	;键码暂存器←"04H"
		JMP	KSERV_END1	;转KSERV_END1蜂鸣,继续
;
;***************
;*【7】键处理 *
;***************
KEY_7:	
		SZ	WRITE_EN2
		JMP	KEY_7_1		;禁止写码,转KEY_CLR_1继续
		SNZ	WRITE_EN1	;检查写码允许标志1
		JMP	KEY_7_1		;禁止写码,转KEY_CLR_1继续
		SET	WRITE_EN2	;写码允许2标志置位(已输入"7"键)
		CLR	KEY_CNT		;键入次数计数器清"0"
		JMP	KSERV_END2	;转KSERV_END2,蜂鸣,不累计键入次数
;
KEY_7_1:	
		MOV	A,07H
		MOV	KEY_DAT_BUF,A	;键码暂存器←"07H"
		JMP	KSERV_END1	;转KSERV_END1蜂鸣,计键入次数,继续
;

⌨️ 快捷键说明

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