📄 fdm_key.asm
字号:
;
; ┏━━━━━━━━━━━━━┓
; ┃┏━━━━━━━━━━━┓┃
; ┃┃防盗门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 + -