📄 家居安全多功能报警系统程序.txt
字号:
附录
;------------------------------变量定义
TEMPERATURE_H EQU 20H ;温度高字节
TEMPERATURE_L EQU 21H ;温度低字节
T_INT EQU 23H ;所采温度的整数部分
FLAG_DS18B20 EQU 10H ;DS18B20存在标志
DQ BIT P0.3 ;DS18B20数据端
FLAG_FIRE EQU 24H ;火警标志位,01H有效,00H无效
FLAG_HT BIT P0.4 ;防盗检测端
FLAG_CO BIT P0.5 ;CO连接位,0有效,1无效
FLAG_LOCK EQU 61H ;防盗标志位,01H关闭,00H开启
KEY_SWICH BIT P3.5 ;防盗开关,1无效,0有效
E BIT P0.2 ;LCD1602使能端
RW BIT P0.1 ;LCD1602读/写选择端
RS BIT P0.0 ;LCD1602数据/命令选择端
SDA1 BIT P3.7 ;I2C串行数据/地址端
SCL1 BIT P3.6 ;I2C串行时钟端
SOUND BIT P3.4 ;语音提示连接端
WR_BUF EQU 33H ;6位密码存储地址
RD_BUF EQU 41H ;6位密码缓冲地址
CMD_BYTE EQU 31H ;LCD1602命令入口参数
DAT_BYTE EQU 32H ;LCD1602数据入口参数
AD EQU 30H ;按键值
POINTER EQU 51H ;6位密码在I2C上的存储地址
;------------------------------主程序
ORG 0000
JMP MAIN
MAIN:
MOV FLAG_LOCK,#00H
CLR P3.4
MOV SP,60H
CLR FLAG_CO ;程序初始化
LOOP1:
LCALL SHOW4 ;安全显示程序调用
LCALL FIRE_CHECK1 ;防火程序调用
LCALL CO_CHECK1 ;防煤气程序调用
LCALL HT_CHECK ;防盗程序调用
LJMP LOOP1
;------------------------------主程序完
;------------------------------FIRE程序
FIRE_CHECK1:
MOV B,#09H
MOV A,FLAG_FIRE
LCALL FIRE
CJNE A,#00H,FIRE_CHECK2
JMP FIRE_CHECK3
FIRE_CHECK2:
LCALL FIRE
MOV A,FLAG_FIRE
CJNE A,#00H,FIRE_CHECK3
DEC B
MOV A,B
CJNE A,#00H,FIRE_CHECK2 ;防火9次循环检查
LCALL SHOW1
LCALL BELL ;火灾报警
FIRE_CHECK3:
RET
;------------------------------CO程序
CO_CHECK1:
MOV A,#0AH
MOV C,FLAG_CO
JNC CO_CHECK2
JMP CO_CHECK3
CO_CHECK2:
MOV C,FLAG_CO
JC CO_CHECK2
DEC A
CJNE A,#00H,CO_CHECK2 ;煤气10次循环检查
LCALL SHOW3
LCALL BELL ;煤气报警
CO_CHECK3:
RET
;------------------------------防盗程序
HT_CHECK:
MOV C,KEY_SWICH
JNC KEY_1 ;防盗开关检查
MOV FLAG_LOCK,#00H
LCALL SAFE_CHECK
MOV A,FLAG_LOCK
CJNE A,#01H,KEY_1
MOV C,P0.4
JNC KEY_1
MOV A,#09H
HT_CHECK1:
MOV C,P0.4
JNC KEY_1
DEC A
CJNE A,#00H,HT_CHECK1 ;防盗10循环检查
LCALL SHOW2
LCALL BELL ;防盗报警
KEY_1:
RET
;------------------------------键盘主程序
SAFE_CHECK:
LCALL KEY_WORDS
MOV A,AD
CJNE A,#16,END4 ;检查是否按下16功能键,16为键盘使用开关
LCALL KEY_CHECK ;检查按下的键是否弹起来
LCALL KEY_CHECK3 ;检查是否有键按下
MOV A,AD
CJNE A,#15,KEY_14 ;检查是否按下15键功能键
JMP KEY_AN ;进入密码确认程序
KEY_14:
CJNE A,#14,END4 ;检查是否按下14键功能键
JMP KEY_CHANG ;进入密码修改程序
KEY_AN:
LCALL KEY_O ;调用密码输入程序
LCALL RD_NB1 ;调用密码从I2C送到缓冲区程序
LCALL KEY_COMP ;调用密码比较程序
JMP END4
KEY_CHANG:
LCALL KEY_O
LCALL RD_NB1
LCALL KEY_COMP
MOV A,FLAG_LOCK
CJNE A,#01,END4 ;判断密码是否输入正确
L14_AN:
LCALL KEY_CHECK3
MOV A,AD
CJNE A,#14,L14_AN
LCALL KEY_O
LCALL WR_NB1 ;将新密码送入I2C,并覆盖原来的密码
END4:
RET
;-----------------------------密码输入
KEY_O:
MOV B,#06H
MOV R1,#WR_BUF
KEY_OO: LCALL KEY_CHECK
LCALL KEY_CHECK3
MOV A,AD
MOV @R1,A
INC R1
DJNZ B,KEY_OO ;判断6位密码是否输入完成
RET
;-----------------------------密码比较
KEY_COMP:
MOV R3,#6
MOV R0,#33H
MOV R1,#41H
CHECK_KEY:
MOV A,@R1
MOV B,@R0
CJNE A,B,WELL ;相应位的密码比较
INC R0
INC R1
DJNZ R3,CHECK_KEY
MOV FLAG_LOCK,#01
JMP END5
WELL:
SETB C
MOV P3.4,C ;语音提示报警
BELL_CLOSE:
LCALL KEY_CHECK
LCALL KEY_CHECK3
CJNE A,#14,BELL_CLOSE
CLR P3.4
MOV FLAG_LOCK,#00
END5:
RET
;------------------------------键盘扫描程序
KEY_WORDS:
MOV P2,#0FH ;P0-3输出1,作为输入位
MOV A,P2
ANL A,#0FH
CJNE A,#0FH,KEY_AN1
MOV AD,#20
JMP END1
KEY_AN1:
LCALL KEY_RE
END1:
RET
KEY_RE:
ACALL DELAY_1 ; 延时去键抖
MOV A ,P2
ANL A,#0FH
CJNE A,#0FH,HAVE1
MOV A,#20
MOV AD,A
JMP END2
HAVE1:
LCALL HAVE
END2:
RET
HAVE:
MOV A,#0EFH ;行扫描码
NEXT:
MOV B,A
MOV P2,A
MOV A,P2
ANL A,#0FH ;检测列
CJNE A,#0FH,YES
END3:
MOV A,B
RL A
CJNE A,#0FEH,NEXT
YES:
ORL A,#0F0H ;高四位置1
CPL A
MOV R2,#00H
MOV R2,A ;存列码
MOV A,B ;取行码,
CPL A
ORL A,R2 ;列码+行码=键值
MOV AD,#00H
ACALL DISPKEYV
RET
DISPKEYV:
KEY0:
CJNE A,#11H,KEYC_1
LJMP KEYB_1
KEYC_1:
LJMP KEY1
KEYB_1:
LJMP WORD0
KEY1:
CJNE A,#12H,KEY2
LJMP WORD1
KEY2:
CJNE A,#14H,KEY3
LJMP WORD2
KEY3:
CJNE A,#18H,KEY4
LJMP WORD3
KEY4:
CJNE A,#21H,KEY5
LJMP WORD4
KEY5:
CJNE A,#22H,KEY6
LJMP WORD5
KEY6:
CJNE A,#24H,KEY7
LJMP WORD6
KEY7:
CJNE A,#28H,KEY8
LJMP WORD7
KEY8:
CJNE A,#41H,KEY9
LJMP WORD8
KEY9:
CJNE A,#42H,KEY10
LJMP WORD9
KEY10:
CJNE A,#44H,KEY11
LJMP WORD10
KEY11:
CJNE A,#48H,KEY12
LJMP WORD11
KEY12:
CJNE A,#81H,KEY13
LJMP WORD12
KEY13:
CJNE A,#82H,KEY14
LJMP WORD13
KEY14:
CJNE A,#84H,KEY15
LJMP WORD14
KEY15:
CJNE A,#88H,PASS
LJMP WORD15
WORD0:
MOV AD,#01
LJMP PASS
WORD1:
MOV AD,#02
LJMP PASS
WORD2:
MOV AD,#03
LJMP PASS
WORD3:
MOV AD,#04
LJMP PASS
WORD4:
MOV AD,#05
LJMP PASS
WORD5:
MOV AD,#06
LJMP PASS
WORD6:
MOV AD,#07
LJMP PASS
WORD7:
MOV AD,#08
LJMP PASS
WORD8:
MOV AD,#09
LJMP PASS
WORD9:
MOV AD,#10
LJMP PASS
WORD10:
MOV AD,#11
LJMP PASS
WORD11:
MOV AD,#12
LJMP PASS
WORD12:
MOV AD,#13
LJMP PASS
WORD13:
MOV AD,#14
LJMP PASS
WORD14:
MOV AD,#15
LJMP PASS
WORD15:
MOV AD,#16
PASS:
RET
DELAY_1:
MOV R5,#10
D1:
MOV R6,#250
DJNZ R7, $
DJNZ R5,D1
RET
;--------------------------------键弹起确定
KEY_CHECK:
MOV B,AD
KEY_CHECK1:
LCALL KEY_WORDS
MOV A,AD
CJNE A,B,KEY_CHECK2
JMP KEY_CHECK1
KEY_CHECK2:
RET
;--------------------------------键按下确定
KEY_CHECK3:
LCALL KEY_WORDS
MOV A,AD
CJNE A,#20,KEY_CHECK4
JMP KEY_CHECK3
KEY_CHECK4:
RET
;---------------------------------温度程序
FIRE:
LCALL GET_TEMPERATURE ;读取温度
LCALL TEMPERATURE_COV ;温度数据处理
MOV A,T_INT
CLR C
SUBB A,#05AH
JNC FIRE_WARM
MOV FLAG_FIRE,#00
JMP FIRE_COLD
FIRE_WARM:
MOV FLAG_FIRE,#01
FIRE_COLD:
RET
;---------------------------------读出DS18B20转换后的温度值子程序
GET_TEMPERATURE:
MOV A,R2
PUSH ACC
MOV A,R0
PUSH ACC
SETB DQ
LCALL INIT_1820
JB FLAG_DS18B20,GET_TEMPERATURE_1
POP ACC
MOV R0,A
POP ACC
MOV R2,A
RET ; 若DS18B20不存在则返回主程序
GET_TEMPERATURE_1:
LCALL DELAY1
MOV A,#0CCH ; 跳过ROM区
LCALL WRITE_1820
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
MOV R0,#50
LCALL D_ELAY
LCALL INIT_1820
JB FLAG_DS18B20,GET_TEMPERATURE_2
POP ACC
MOV R0,A
POP ACC
MOV R2,A
RET ; 若DS18B20不存在则返回主程序
GET_TEMPERATURE_2:
LCALL DELAY1
MOV A,#0CCH ; 跳过ROM区
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_1820 ;READ_1820
POP ACC
MOV R0,A
POP ACC
MOV R2,A
RET
;------------------------------写一个字节到DS18B20子程序
WRITE_1820:
MOV R2,#8
CLR C
WRITE_1820_1:
CLR DQ
MOV R3,#6
DJNZ R3,$
RRC A
MOV DQ,C
MOV R3,#23
DJNZ R3,$
SETB DQ
NOP
DJNZ R2,WRITE_1820_1
SETB DQ
RET
;------------------------------从DS18B20中读出两个字节的温度数据
READ_1820:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TEMPERATURE_L ; 低位存入21H(TEMPERATURE_L),高位存入20H(TEMPERATURE_H)
READ_1820_1:
MOV R2,#8 ;数据一共有8位
READ_1820_2:
CLR C
SETB DQ
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R3,#8
DJNZ R3,$
MOV C,DQ
MOV R3,#22
DJNZ R3,$
RRC A
DJNZ R2,READ_1820_2
MOV @R1,A
DEC R1
DJNZ R4,READ_1820_1
RET
;------------------------------DS18B20初始化程序
INIT_1820:
SETB DQ
NOP
CLR DQ
MOV R0,#36 ;主机发出延时540微秒的复位低脉冲
LCALL D_ELAY
SETB DQ
NOP
NOP
MOV R0,#25H ;96US-25H
INIT_1820_1:
DJNZ R0,INIT_1820_1
JNB DQ,INIT_1820_2
LJMP INIT_1820_3 ; 延时
INIT_1820_2:
SETB FLAG_DS18B20 ; 置标志位,表示DS1820存在
LJMP INIT_1820_4
INIT_1820_3:
CLR FLAG_DS18B20 ; 清标志位,表示DS1820不存在
LJMP INIT_1820_6
INIT_1820_4:
MOV R0,#6BH ;延时200US
INIT_1820_5:
DJNZ R0,INIT_1820_5
INIT_1820_6:
SETB DQ
SETB P1.0
JNB FLAG_DS18B20,INIT_END
CLR P1.0 ;点亮第一个LED,代表DS18B20存在
INIT_END:
RET
;------------------------------将从DS18B20中读出的温度数据进行转换
TEMPERATURE_COV:
MOV A,#00H
MOV T_INT,A
CLR C
MOV A,#0F0H ;提取所采集温度的整数部分并存储到T_INT
ANL A,TEMPERATURE_L
SWAP A
MOV T_INT,A
MOV A,TEMPERATURE_H
ANL A,#07H
SWAP A
ORL A,T_INT
MOV T_INT,A
RET
;------------------------------延时子程序
D_ELAY:
LOOP:
MOV R1,#06H
LOOP2:
DJNZ R1,LOOP2
DJNZ R0,LOOP
RET
;-------------------------------
DELAY1:
MOV R7,#20H
DJNZ R7,$
RET
;-------------------------------
DELAY1MS:
MOV R5,#247
DJNZ R5,$
RET
;-------------------------------显示
SHOW1:
LCALL LCDINIT
MOV DPTR,#TAB1
LCALL DISP1
MOV DPTR,#TAB4
LCALL DISP2
RET
SHOW2:
LCALL LCDINIT
MOV DPTR,#TAB2
LCALL DISP1
MOV DPTR,#TAB4
LCALL DISP2
RET
SHOW3:
LCALL LCDINIT
MOV DPTR,#TAB3
LCALL DISP1
MOV DPTR,#TAB4
LCALL DISP2
RET
SHOW4:
LCALL LCDINIT
MOV DPTR,#TAB5
LCALL DISP1
MOV DPTR,#TAB5
LCALL DISP2
RET
;--------------------------------LCD1602要用到的一些子程序
;--------------------------------写命令(入口参数CMD_BYTE)
WRITE_CMD:
CLR RS
CLR RW
MOV P1,CMD_BYTE
SETB E
NOP
NOP
CLR E
LCALL DELAY
RET
;--------------------------------写显示数据(入口参数DAT_BYTE)
WRITE_DAT:
SETB RS
CLR RW
MOV A,DAT_BYTE
MOV P1,A
SETB E
NOP
NOP
CLR E
LCALL DELAY
RET
;--------------------------------LCD显示初始化
LCDINIT:
MOV CMD_BYTE,#30H
LCALL WRITE_CMD
MOV CMD_BYTE,#30H
LCALL WRITE_CMD
MOV CMD_BYTE,#30H
LCALL WRITE_CMD
MOV CMD_BYTE,#38H ;设定工作方式
LCALL WRITE_CMD
MOV CMD_BYTE,#0CH ;显示状态设置
LCALL WRITE_CMD
MOV CMD_BYTE,#01H ;清屏
LCALL WRITE_CMD
MOV CMD_BYTE,#06H ;输入方式设置
LCALL WRITE_CMD
RET
;-------------------------------在第一行显示表格1的内容
DISP1:
MOV CMD_BYTE,#80H ;设置DDRAM的地址
LCALL WRITE_CMD
MOV R7,#10H
MOV R6,#00H
DISPMSG1_1:
MOV A,R6
MOVC A,@A+DPTR
MOV DAT_BYTE,A
LCALL WRITE_DAT
INC R6
DJNZ R7,DISPMSG1_1
RET
;-------------------------------在第二行显示表格1的内容
DISP2:
MOV CMD_BYTE,#0C0H ;设置DDRAM的地址
LCALL WRITE_CMD
MOV R7,#10H
MOV R6,#00H
DISPMSG2_1:
MOV A,R6
MOVC A,@A+DPTR
MOV DAT_BYTE,A
LCALL WRITE_DAT
INC R6
DJNZ R7,DISPMSG2_1
RET
;--------------------------------延时子程序
DELAY:
MOV R5,#0A0H
DELAY3:
NOP
DJNZ R5,DELAY3
RET
;--------------------------------要显示的内容
;------------------------表格----------------------------------
TAB1: DB " FIRE "
TAB2: DB " THIEVES "
TAB3: DB " GAS "
TAB4: DB " WARNING "
TAB5: DB " SAFE "
;-----------------------THE END-------------------------------
;;-----向从器件指定单元写6个字节数据-----;;
;;入口:传递的地址在POINTER,数据在WR_BUF中,发送字节数在6中
;;资源占用:ACC、R0、R1、R3、C
WR_NB1:
CLR EA
SETB SDA1
SETB SCL1
LCALL START1
MOV A,#0A0H
LCALL WR8BIT1
LCALL CACK1
MOV POINTER,#00H
MOV A,POINTER
LCALL WR8BIT1
LCALL CACK1
MOV R3,#6
MOV R1,#WR_BUF
WRNB11:
MOV A,@R1
LCALL WR8BIT1
LCALL CACK1
INC R1
DJNZ R3,WRNB11
LCALL STOP1
LCALL DEL10MS
SETB EA
RET
;;-----从从器件指定单元读6个字节数据-----;;
;;入口:传递的地址在POINTER,接收数据缓冲区RD_BUF,接收字节数在N中
;;资源占用:ACC、R0、R1、R3、C
RD_NB1:
MOV R3,#6
RDNB11:
LCALL START1
MOV A,#0A1H
LCALL WR8BIT1
LCALL CACK1
MOV POINTER,#00H
MOV A,POINTER
LCALL WR8BIT1
LCALL CACK1
MOV R1,#RD_BUF
RDB1:
LCALL RD8BIT1
MOV @R1,A
DJNZ R3,SACK1
LCALL MACK1
LCALL STOP1
RET
SACK1:
INC R1
LCALL MACK1
SJMP RDB1
;;-----字节发送-----;;
;;入口:要发送的数据在ACC中
;;每发送完一个字节,要调用一次CACK,以判断是否有应答
WR8BIT1:
PUSH ACC
MOV R0,#08H
WR_BIT1:
RLC A
MOV SDA1,C
NOP
NOP
NOP
NOP
NOP
SETB SCL1
NOP
NOP
NOP
NOP
NOP
CLR SCL1
DJNZ R0,WR_BIT1
POP ACC
RET
;;-----字节接收-----;;
;;出口:接收到的数据在ACC中
;;每接收完一个字节,要调用一MCACK/MNACK
RD8BIT1:
MOV R0,#08H
RD_BIT1:
SETB SDA1
NOP
NOP
NOP
NOP
NOP
SETB SCL1
NOP
NOP
NOP
NOP
NOP
MOV C,SDA1
RLC A
NOP
NOP
NOP
NOP
NOP
CLR SCL1
DJNZ R0,RD_BIT1
CLR SDA1
RET
;;-----启动-----;;
START1:
NOP
NOP
NOP
NOP
NOP
SETB SDA1
NOP
NOP
NOP
NOP
NOP
SETB SCL1
NOP
NOP
NOP
NOP
NOP
CLR SDA1
NOP
NOP
NOP
NOP
NOP
CLR SCL1
NOP
NOP
NOP
NOP
NOP
RET
;;-----结束-----;;
STOP1:
NOP
NOP
NOP
NOP
NOP
SETB SCL1
NOP
NOP
NOP
NOP
NOP
SETB SDA1
NOP
NOP
NOP
NOP
NOP
RET
;;-----应答检查-----;;
CACK1:
SETB SDA1
NOP
NOP
NOP
NOP
NOP
SETB SCL1
NOP
NOP
NOP
NOP
NOP
MOV C,SDA1
JC CACK1
CLR SCL1
CLR SDA1
LCALL DELAY1MS
RET
;;-----应答-----;;
MACK1:
CLR SDA1
NOP
NOP
NOP
NOP
NOP
SETB SCL1
NOP
NOP
NOP
NOP
NOP
CLR SCL1
NOP
NOP
NOP
NOP
NOP
SETB SDA1
RET
;;-----10MS延时------;;
DEL10MS :
MOV R6,#10
DELAY2:
MOV R7,#249
DELAY5: NOP
NOP
DJNZ R7,DELAY5
DJNZ R6,DELAY2
NOP
NOP
NOP
NOP
RET
;-------语音报警-------;;
BELL:
SETB C
MOV P3.4,C
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -