📄 fdm_key.asm
字号:
;****************************
;* 第二行键值分析 *
;*--------------------------*
;* PA.0 PA.1 PA.2 PA.3 *
;* COL1 COL2 COL3 COL4 *
;* 【2】【5】【8】【0】 *
;****************************
KSERV2:
MOV A,LINE ;取出第二行新键值
MOV LINE2,A ;更新第二行键值寄存器
SNZ ACC.0 ;检查COL1是否为"0"
JMP KEY_2 ;是【2】键有按下,转KEY_2键处理
SNZ ACC.1 ;检查COL2是否为"0"
JMP KEY_5 ;是【5】键有按下,转KEY_5键处理
SNZ ACC.2 ;检查COL3是否为"0"
JMP KEY_8 ;是【8】键有按下,转KEY_8键处理
SNZ ACC.3 ;检查COL4是否为"0"
JMP KEY_0 ;是【0】键有按下,转KEY_0键处理
JMP KSERV_END ;无按键,转KSERV_END,键处理结束
;
;***************
;*【2】键处理 *
;***************
KEY_2: MOV A,02H
MOV KEY_DAT_BUF,A ;键码暂存器←"02H"
JMP KSERV_END1 ;转KSERV_END1蜂鸣,继续
;
;***************
;*【5】键处理 *
;***************
KEY_5: MOV A,05H
MOV KEY_DAT_BUF,A ;键码暂存器←"05H"
JMP KSERV_END1 ;转KSERV_END1蜂鸣,继续
;
;***************
;*【8】键处理 *
;***************
KEY_8:
SNZ WRITE_EN0 ;检查写码允许标志
JMP KEY_8_1 ;禁止写码,转KEY_8_1继续
SET WRITE_EN1 ;写码允许1标志置位(已输入"8"键)
;
KEY_8_1: MOV A,08H
MOV KEY_DAT_BUF,A ;键码暂存器←"08H"
JMP KSERV_END1 ;转KSERV_END1蜂鸣,继续
;
;***************
;*【0】键处理 *
;***************
KEY_0: MOV A,00H
MOV KEY_DAT_BUF,A ;键码暂存器←"00H"
JMP KSERV_END1 ;转KSERV_END1蜂鸣,继续
;
;****************************
;* 第三行键值分析 *
;*--------------------------*
;* PA.0 PA.1 PA.2 PA.3 *
;* COL1 COL2 COL3 COL4 *
;* 【3】【6】【9】【#】 *
;****************************
KSERV3: MOV A,LINE ;取出第三行新键值
MOV LINE3,A ;更新第三行键值寄存器
SNZ ACC.0 ;检查COL1是否为"0"
JMP KEY_3 ;是【3】键有按下,转KEY_3键处理
SNZ ACC.1 ;检查COL2是否为"0"
JMP KEY_6 ;是【6】键有按下,转KEY_6键处理
SNZ ACC.2 ;检查COL3是否为"0"
JMP KEY_9 ;是【9】键有按下,转KEY_9键处理
SNZ ACC.3 ;检查COL4是否为"0"
JMP KEY_OPEN ;是【#】键有按下,转KEY_OPEN键处理
JMP KSERV_END ;无按键,转KSERV_END,键处理结束
;
;***************
;*【3】键处理 *
;***************
KEY_3: MOV A,03H
MOV KEY_DAT_BUF,A ;键码暂存器←"03H"
JMP KSERV_END1 ;转KSERV_END1蜂鸣,继续
;
;***************
;*【6】键处理 *
;***************
KEY_6: MOV A,06H
MOV KEY_DAT_BUF,A ;键码暂存器←"06H"
JMP KSERV_END1 ;转KSERV_END1蜂鸣,继续
;
;***************
;*【9】键处理 *
;***************
KEY_9: MOV A,09H
MOV KEY_DAT_BUF,A ;键码暂存器←"09H"
JMP KSERV_END1 ;转KSERV_END1蜂鸣,继续
;
;***************
;*【#】键处理 *
;***************
KEY_OPEN: INC OPEN_KEY_CNT ;【#】键计数器加一
;
MOV A,OPEN_KEY_CNT ;检查【#】键计数器
XOR A,01H
SZ ACC
JMP KEY_OPEN1 ;不是"1"次,转KEY_OPEN1继续
;***************************
;* 已按下"1"次【#】键处理 *
;***************************
SNZ KEY_6_OK ;检查按"#"前,数字键是否按过6位数码
JMP KEY_OPEN3 ;未按满6位数字键,转KEY_OPEN3处理
;****************************
;* 6位码已按过,【#】键有效 *
;****************************
SET OPEN_EN ;开门允许标志置位
JMP KEY_OPEN_END
;
;****************************
;* 未满6次时,按【#】键处理 *
;****************************
KEY_OPEN3: SZ KEY_CNT ;检查数码键计数器
JMP ALM_DOWN_CL ;转出错处理
JMP KEY_OPEN_END ;="0",【#】键无效
;
;***********************************
;* 欠次开门出错处理,不累计出错次数 *
;***********************************
ALM_DOWN_CL: SET ALM_DOWN ;欠次开门出错标志置位
SET ALM_EN ;报警允许标志置位
CLR OPEN_EN ;开门允许标志复位
CLR KEY_CNT ;键入次数计数器清"0"
CLR MODI_EN ;改码键标志复位
CLR OPEN_KEY_CNT ;【#】键计数器清"0"
JMP KEY_OPEN_END ;处理结束
;
;************************
;* 检查按下几次【#】键 *
;************************
KEY_OPEN1: MOV A,OPEN_KEY_CNT ;检查【#】键计数器
XOR A,02H
SZ ACC
JMP KEY_OPEN2 ;不是"2"次,转KEY_OPEN2继续
;
SNZ MODI_EN ;检查改码允许键按下标志
JMP KEY_OPEN2 ;未按过,禁止改码操作
;********************
;* 改码允许键已按过 *
;********************
SET WRITE_EN0 ;允许改码标志置位(已输入2次"#"键)
JMP KEY_OPEN_END
;
;*******************************
;* 不是"1","2"次按【#】键处理 *
;*******************************
KEY_OPEN2: CLR OPEN_KEY_CNT ;【#】键计数器清"0"
;
KEY_OPEN_END: JMP KSERV_END2 ;转KSERV_END1蜂鸣,继续
;
;********************
;* ◆检查秒定时器◆ *
;********************
TI3: SDZ MST_CNT
JMP TIO_END ;1S未到,出去
MOV A,100
MOV MST_CNT,A ;重置秒计数器(100x10ms=1s)
;
;*****************
;* ◆1秒定时到◆ *
;*****************
SNZ ALM_LOW_EN ;检查低电压报警允许标志
JMP TI44 ;="0",禁止报警延时
SDZ BAT_LOW_TIM ;低电压报警定时减1,
JMP TI44 ;≠"0",出去
CLR BAT_LOW_ES ;低电压报警延时标志复位
;
;//////////////////////////////////////////////
TI44: SNZ HALT_TIM_EN ;检查冬眠定时允许标志
JMP TI4 ;HALT_TIM_EN="0",转TI4,禁止冬眠定时
;
SZ HALT_TIM ;冬眠定时器减"1"
JMP TI5 ;定时不为"0",转TI4继读
JMP TI6
;
TI5: DEC HALT_TIM
JMP TI4
TI6: MOV A,HALT_SET ;重置1分钟冬眠定时
MOV HALT_TIM,A
;******************************
;* 若为欠压状态,则延长到250秒 *
;******************************
SNZ ALM_LOW_EN ;检查低电压报警允许标志
JMP TI_BAT ;="0",延时60秒
MOV A,HALT_LOW_SET ;重置250秒冬眠定时
MOV HALT_TIM,A
;
TI_BAT: CLR HALT_TIM_EN ;冬眠定时允许标志复位
SET HALT_EN ;允许冬眠标志置位
;/////////////////////////////////////////////
TI4: SNZ ALM_TIM_EN ;检查报警允许标志
JMP R_TI16 ;="0",禁止报警
;
SZ ALM_TIM ;检查报警间隔定时器
DEC ALM_TIM ;≠"0",报警间隔定时减"1"
;
R_TI16: SNZ ALM_KEY_EN ;检查超次延时允许标志
JMP R_TI15 ;="0",禁止超次延时
SDZ ALM_KEY_TIM ;超次延时计数器减1
JMP R_TI15 ;≠"0",则继续
CLR ALM_KEY_EN ;超次延时允许标志复位
;
;**********************************
;* ◆1秒定时到,马达正转关闭定时◆ *
;**********************************
R_TI15: SNZ MD_ZZ_OFF_ES ;检查马达正转关闭定时标志
JMP TIO_END ;禁止延时,转TIO_END出去
SZ MD_OFF_CNT ;检查马达正转关闭定时计数器
DEC MD_OFF_CNT ;不为"0",定时器减一
;
TIO_END: MOV A,TMPE1 ;恢复现场
RETI
;
;**************************
;* 蜂鸣子程序 *
;* 蜂鸣一次: BEE←"1" *
;* 初始化: FM_CNT←"01" *
;* 蜂鸣次数: FM_CNT←"xx" *
;**************************
BEEP:
SNZ BEE ;检查蜂鸣允许标志
JMP BEE_END
;
SZ FM_ON
JMP BEEP1 ;正在开蜂鸣延时,转BEEP1继续
SZ FM_OFF
JMP BEEP2 ;正在关蜂鸣延时,转BEEP2继续
;
MOV A,08 ;正常蜂鸣短声
MOV FM_TIM,A ;设定开蜂鸣定时器
SNZ ALM_EN
JMP BEE_FRE1
MOV A,32 ;出错报警长声
MOV FM_TIM,A ;设定开蜂鸣定时器
BEE_FRE1: SET FM_ON ;开蜂鸣标志置位
;
BEEP1:
SZ FM_TIM
JMP BEE_END ;开蜂鸣延时未到,转出口
;
CLR FM_ON ;开蜂鸣标志复位
SET FM ;蜂鸣器控制线置"1",关蜂鸣
MOV A,08
MOV FM_TIM,A ;设定关蜂鸣定时器
SET FM_OFF ;关蜂鸣标志置位
;
BEEP2: SZ FM_TIM
JMP BEE_END ;关蜂鸣延时未到,转出口
CLR FM_OFF ;关蜂鸣标志复位
SDZ FM_CNT
JMP BEE_END ;蜂鸣次数未到,出去
CLR BEE ;蜂鸣次数到,禁止蜂鸣
INC FM_CNT ;常置蜂鸣一次
BEE_END: NOP
;
;**********************
;* 定时到报警蜂鸣处理 *
;**********************
SNZ ALM_EN ;检查报警允许标志
JMP ALM_END ;ALM_EN="0",禁止报警
;****************
;* 报警允许处理 *
;****************
SZ ALM_TIM_EN ;检查报警间隔定时允许标志
JMP ALM3 ;ALM_TIM_EN="1",转ALM3正在间隔定时
;
SZ ALM_LOP ;检查报警循环标志
JMP ALM1 ;ALM_LOP="1",转ALM1
;
MOV A,ALM_SET2
MOV ALM_CNT,A ;设定遍数
SET ALM_LOP ;报警循环标志置位
;
ALM2: SET BEE ;蜂鸣允许
MOV A,ALM_SET1 ;设定每遍蜂鸣次数(长叫2次)
MOV FM_CNT,A
SZ ALM_DOWN ;检查欠次开门出错标志
DEC FM_CNT ;是,则长叫一次
;
ALM1: SZ BEE
JMP ALM_END ;4次未叫完,转ALM_END出去
MOV A,ALM_TIM_SET ;取出间隔时间预置值
MOV ALM_TIM,A ;设定每遍间隔定时
SET ALM_TIM_EN ;报警间隔定时允许标志置位
;
ALM3: SZ ALM_TIM
JMP ALM_END ;间隔定时未结束,转ALM_END出去
CLR ALM_TIM_EN ;报警间隔定时允许标志复位
SDZ ALM_CNT ;报警遍数减"1"
JMP ALM2 ;遍数未到,转ALM2循环
;
CLR ALM_LOP ;报警循环标志复位
CLR ALM_EN ;禁止报警
CLR ALM_DOWN ;欠次开门出错标志复位
SET FM ;蜂鸣器控制线置"1",关蜂鸣
;
ALM_END: RET
;
;********************************************
;* 写数据操作码 *
;* SCL="1"时,SDA ̄\_为起始位 *
; *
;* SCL="1"时,SDA_/ ̄为停止位 *
; __________ *
;* HT2201芯片操作地址:|1|0|1|0|0|0|0| R/W| *
;* 左边信息高位先送出  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ *
;* 读操作: R/W="1",写操作: R/W="0" *
;********************************************
;
;**************************
;* ◆发送起始信号子程序◆ *
;**************************
STRT:
CLR SDA_C ;定义数据脚为输出口
CLR SCL ;时钟脚 ̄\_
SET SDA ;数据脚←"1"
SET SCL ;时钟脚_/ ̄
CLR SDA ;数据脚←"0",起始信号
CLR SCL ;时钟脚 ̄\_
RET
;
;**************************
;* ◆发送停止信号子程序◆ *
;**************************
STOP:
CLR SDA_C ;定义数据脚为输出口
CLR SDA ;数据脚←"0"
SET SCL ;时钟脚_/ ̄
SET SDA ;数据脚←"1",停止信号
CLR SCL ;时钟脚 ̄\_
RET
;
;**********************
;* ◆字节写入子程序◆ *
;* 入口: A←待写内容 *
;**********************
WBYTE:
MOV BYTE_DAT,A ;待写内容暂存于A
CLR SCL ;时钟脚 ̄\_
CLR SDA_C ;定义数据脚为输出口
MOV A,08H
MOV DATA_8,A ;预置写入数据长度计数器
WBYTE1:
CLR SDA ;数据脚←"0"
SZ BYTE_DAT.7 ;检查待写内容最高位=?
SET SDA ;最高位≠"0",则数据脚←"1"
SET SCL ;时钟脚_/ ̄\_ ,发送当前数据位
CLR SCL
RL BYTE_DAT ;待写内容字节左环移一位,准备下一位数据
SDZ DATA_8 ;写入数据长度减一,并检查是否为"0"
JMP WBYTE1 ;≠"0",转WBYTE1循环
SET SDA_C ;定义数据脚为输入口
SET SCL ;时钟脚_/ ̄,CPU准备收2201的应答信号
WBYTE2:
SZ SDA ;检查数据脚状态
JMP WBYTE2 ;≠"0",转WBYTE2,等待应答信号
RET
;
;********************************
;* ◆字节写入子程序(无应答位)◆ *
;* 入口: A←待写内容 *
;********************************
WBYTE_NO:
MOV BYTE_DAT,A ;待写内容暂存于A
CLR SCL ;时钟脚 ̄\_
CLR SDA_C ;定义数据脚为输出口
MOV A,08H
MOV DATA_8,A ;预置写入数据长度计数器
WBYTE_NO1:
CLR SDA ;数据脚←"0"
SZ BYTE_DAT.7 ;检查待写内容最高位=?
SET SDA ;最高位≠"0",则数据脚←"1"
SET SCL ;时钟脚_/ ̄\_ ,发送当前数据位
CLR SCL
RL BYTE_DAT ;待写内容字节左环移一位,准备下一位数据
SDZ DATA_8 ;写入数据长度减一,并检查是否为"0"
JMP WBYTE_NO1 ;≠"0",转WBYTE1循环
SET SCL ;时钟脚_/ ̄\_ ,发送当前数据位
CLR SCL
RET
;
;**********************
;* ◆字节读出子程序◆ *
;* 出口: A←读出内容 *
;**********************
RBYTE:
SET SCL ;时钟脚_/ ̄
SET SDA_C ;定义数据脚为输入口
MOV A,08H
MOV DATA_8,A ;设传输数据长度8
RBYTE1:
SET SCL ;时钟脚_/ ̄
NOP
NOP
NOP
NOP
NOP ;延时
CLR SCL ;时钟脚 ̄\_
NOP
NOP
NOP
NOP
NOP ;延时
RL READ_OUT ;读出数据字节左环移一位,准备下一位数据
CLR READ_OUT.0 ;读入数据字节最低位←"0" (从低位到高位)
SZ SDA ;检查数据线状态,="0"?
SET READ_OUT.0 ;≠"0",则读入数据字节最低位←"1"
SDZ DATA_8 ;数据长度减一,并检查是否为"0"
JMP RBYTE1 ;≠"0",转RBYTE1循环
MOV A,READ_OUT ;A←读出内容
RET
;
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -