📄 fdm_key.asm
字号:
;* 正转开启定时到 *
;******************
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 + -