📄 家庭无线报警系统1.asm
字号:
;采用AT89S51单片机,晶振11.0592MHZ,通讯速率9600,采用TTL串口通讯
;LED缓存第1行是40H-4FH,上面行
;LED缓存第2行是30H-3FH,下面行
;手机号码缓存在50H-5BH的12个内存中
;密码"车辆报警"存放在5CH-73H的24个内存中6个中文字
;手机号码存放在74H-7FH的12个内存中
;设防标志存放在位地址7FH中
ORG 0000H
AJMP MAIN;转入主程序
ORG 0003H ;外部中断P3.2脚INT0入口地址
NOP
NOP
NOP
NOP
NOP
NOP
RETI
ORG 000BH;中断陷阱
NOP
NOP
NOP
NOP
NOP
NOP
RETI
ORG 0013H;中断陷阱
NOP
NOP
NOP
NOP
NOP
NOP
RETI
ORG 001BH;中断陷阱
NOP
NOP
NOP
NOP
NOP
NOP
RETI
ORG 0023H
NOP
NOP
NOP
NOP
RETI
LCD_RS BIT P2.0;RS
LCD_RW BIT P2.1;RW
LCD_EN BIT P2.2;E
FOK EQU P1.0;定义为啦叭
SX EQU P1.1;定义手机模块上线标志
SJKJ EQU P1.2;定义手机模块激活控制端
; SJGJ EQU P2.3;定义手机模块关机控制端
; EQU P2.4;定义
LED EQU P1.7;定义
; EQU P2.6;定义
DY EQU P1.6;定义电源断线控制端
VT EQU P3.2;定义解码有效标志
DM EQU P3.4;定义大门控制端
HW EQU P3.5;定义红外报警端
YKSF EQU P3.6;定义遥控设防端
YKJSF EQU P3.7;定义遥控解设防端
DD EQU P3.3;定义低电压报告
MAIN:
CALL SET_LCD;LCD 初始化设置
CLR SJKJ
;以下为主程序进行CPU中断方式设置
SETB IT0 ;设定INT0的触发方式为脉冲负边沿触发,报警触发控制端
MOV SCON,#50H;设置成串口1方式
MOV TMOD,#20H;波特率发生器T1工作在模式2上
MOV TH1,#0FDH;预置初值(按照波特率9600BPS预置初值)
MOV TL1,#0FDH;预置初值(按照波特率9600BPS预置初值)
SETB TR1;启动定时器T1
MOV PCON,#00H
LCALL YUSJ;开机清除接收短消息手机号码
SETB SJKJ;打开手机
MOV DPTR,#500;延时500ms
LCALL DELAYXMS;开机延时
CLR SJKJ;复位手机控制
LCALL ATE0OK;开机发送ATE0指令!
LCALL CNMI ;发送(AT+CNMI=1,1,0,0,1),短信到达TE 新信息指示
LCALL SCQBDX;调用删除SIM卡中所有短信的子程序
;完成和手机通信握手,和SIM卡删除所有短消息初始化
START:
LCALL XRSJ;读出授权电话号码及密码,写入内存中
LCALL MJCS;串口接收模块数据OK响一声
LCALL MJCS;串口接收模块数据OK响一声
CLR SX;模块上线
;**********************************************
KKS:
JB RI,UART;检测到RI变1就退出
JB VT,PDYKSH;解码有效标志=0则转PDYKSH判断遥控信号
JB RI,UART;检测到RI变1就退出
JNB DY,DYBJ;电源断线控制端=0则转DYBJ电源报警
AJMP KKS
;**********************************************
PDYKSH:
MOV DPTR,#10;延时10mS
LCALL DelayXmS;开机延时
JB VT,PDYKSH;延时防止误码报
JB DM,DMBJ;大门报警端=0则转DMBJ大门报警
JB HW,HWBJ;红外报警端=0则转HWBJ红外报警
JB YKSF,YKSFSZ;遥控设防端=0则转遥控设防设置
JB YKJSF,YKJSFSZ;遥控解设防端=0则转遥控解设防设置
AJMP KKS
;**********************************************
UART:
LJMP UARTI
DYBJ:;电源报警
LCALL FDYBJ
AJMP KKS
DMBJ:;大门报警
JB LED,KKS;如果设防标志SFBZ=0则退出
LCALL FDMBJ
AJMP KKS
HWBJ:;红外报警
JB LED,KKS;如果设防标志SFBZ=0则退出
LCALL FHWBJ
AJMP KKS
YKSFSZ:;设防
CLR LED
AJMP KKS
YKJSFSZ:;解设防
SETB LED
AJMP KKS
;-----------------------------------------------------
;LCD 初始化设置
;-----------------------------------------------------
SET_LCD:
CLR LCD_EN
CALL INIT_LCD ;初始化 LCD
MOV DPTR,#3
LCALL DelayXmS
MOV DPTR,#TAB8 ;指针指到显示信息1
MOV R0,#40H
MOV R1,#0
CALL ZSJ;转数据到显示缓冲区
MOV A,#1 ;显示在第一行
MOV R0,#40H
MOV R1,#0
CALL LCD_SHOW
MOV DPTR,#TAB9 ;指针指到显示信息2
MOV R0,#30H
MOV R1,#0
CALL ZSJ;转数据到显示缓冲区
MOV A,#2 ;显示在第二行
MOV R0,#30H
MOV R1,#0
CALL LCD_SHOW
RET
;-----------------------------------------------------
;转数据到显示缓冲区
;-----------------------------------------------------
ZSJ:
CLR A
MOVC A,@A+DPTR ;由消息区取出字符
MOV @R0,A
INC R0
INC DPTR
INC R1
CJNE R1,#10H,ZSJ
RET
;-----------------------------------------------------
;LCD 接口初始化
;8 位I/O 控制
;-----------------------------------------------------
INIT_LCD:
MOV A,#38H ;双列显示,字形5*7 点阵
CALL WCOM;写入命令
MOV DPTR,#3
LCALL DelayXmS
MOV A,#0CH ;开显示,关光标,
CALL WCOM;写入命令
MOV DPTR,#3
LCALL DelayXmS
MOV A,#01H ;清除 LCD 显示屏
CALL WCOM;写入命令
RET
;----------------------------------------------------
;在LCD 的第一行或第二行显示信息字符
;----------------------------------------------------
LCD_SHOW:
CJNE A,#1,LINE2 ;判断是否为第一行
LINE1: MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
JMP FILL
LINE2: MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM ;写入命令
FILL:
CLR A ;填入字符
MOV A,@R0 ;由消息区取出字符
INC R1
CJNE R1,#11H,LC1;判断是否为结束码
RET
LC1: CALL WDATA ;写入数据
INC R0
JMP FILL ;继续填入字符
RET
;-----------------------------------------------------*/
; 写指令、数据使能子程序
;-----------------------------------------------------
ENABLE: ;写指令使能
CLR LCD_RS ;RS=L,LCD_RW=L,D0-D7=指令码,E=高脉冲
CLR LCD_RW
SETB LCD_EN
CALL DELAY0
CLR LCD_EN
RET
ENABLE1: ;写数据使能
SETB LCD_RS ;RS=H,RW=L,D0-D7=数据,E=高脉冲
CLR LCD_RW
SETB LCD_EN
CALL DELAY0
CLR LCD_EN
RET
DELAY0:
MOV R7,#250 ;延时500 微秒
DJNZ R7,$
RET
;----------------------------------------------------
;写入命令子程序
;----------------------------------------------------
WCOM: ;以8位控制方式将命令写至LCD
MOV P0,A ;写入命令
CALL ENABLE
RET
;----------------------------------------------------
;写入数据子程序
;----------------------------------------------------
WDATA: ;以8位控制方式将数据写至LCD
MOV P0,A ;写入数据
CALL ENABLE1
RET
/*
;报警程序
BAOJIN:
LCALL CPAS;调用模块状态报告子程序
MOV A,25H
CJNE A,#34H,BAOJIN1;判断串口数据如果A不等于#34H则BAOJIN1
AJMP BAOJIN3;如果模块正在呼出或通话,就退出
BAOJIN1:
LCALL CPAS
MOV A,25H
CJNE A,#34H,BAOJIN2
AJMP BAOJIN3;如果模块正在呼出或通话,就退出
BAOJIN2:
LCALL ATH;调用串口发送ATH挂机子程序
LCALL PDOK;判断手机是否回答OK?
JZ BAOJIN2;如果没有检测到OK,重复发
LCALL FBJDX;调用发报警短信子程序
LCALL FSCG;调用短信发送检测子程序
MOV DPTR,#3000;延时5秒
LCALL DelayXmS
LCALL HC;发回车
MOV DPTR,#1000;延时5秒
LCALL DelayXmS
LCALL ATD;调用串口发送"ATD13906079959;"子程序
MOV R3,#14;定义接收手机号码的数据长度0D 0A 4E 4F 20 43 41 52 52 49 45 52 0D 0A NO CARRIER
MOV R0,#30H;数据在内存的存放位置
LCALL GPSSJ;调用接收串口数据子程序
BAOJIN3:
AJMP KKS */
;**********************************************
;**********************************************
;进入串口中断方式接收
UARTI:
CLR RI;清楚串口中断标志
LCALL PDDA;调用串口接收0D/0A数据子程序
LCALL PDRI;等待下一个串口数据
MOV A,SBUF;将串口寄存器中接收到的数据给A
CJNE A,#2BH,PDRD;判断串口数据+
CLR RI;软件清除串口中断标记
LCALL PDRI;等待下一个串口数据
MOV A,SBUF;将串口寄存器中接收到的数据给A
CJNE A,#43H,EXITT1;判断串口数据C
CLR RI;软件清除串口中断标记
LCALL PDRI;等待下一个串口数据
;+CMTI: "SM",7短信到达存放位置
MOV A,SBUF;将串口寄存器中接收到的数据给A
CJNE A,#4DH,EXITT1;判断串口数据M
CLR RI;软件清除串口中断标记
LCALL PDRI;等待下一个串口数据
MOV A,SBUF;将串口寄存器中接收到的数据给A
CJNE A,#54H,EXITT1;判断串口数据T
CLR RI;软件清除串口中断标记
LCALL PDRI;等待下一个串口数据
MOV A,SBUF;将串口寄存器中接收到的数据给A
CJNE A,#49H,EXITT1;判断串口数据I
CLR RI;软件清除串口中断标记
;检测到"+CMTI"的ASCII码--------
;跳过7个内存(: "SM",)
MOV R3,#7;定义接收数据的总长度
LCALL TGSJ;调用接收串口数据子程序
;短信位置,存放在26H中
MOV R0,#26H;数据在内存的存放位置
CLR RI;软件清除串口中断标记
LCALL PDRI;等待下一个串口数据
MOV A,SBUF;将串口寄存器中接收到的数据给A
MOV @R0,A
INC R0;内存单元地址0
;跳过8个内存
MOV R3,#8;定义接收数据的总长度
LCALL TGSJ;调用接收串口数据子程序
LCALL DXNR;解析短信内容
EXITT1:
LJMP EXITT
PDRD:
LCALL RING;电话呼入提示
EXITT:
CLR RI;软件清除串口中断标记,退出串口中断
AJMP KKS
RING3:
JMP RING1
;**********************************************
RING:;电话呼入提示
CLR RI;清除串口中断标志
MOV A,SBUF;将串口寄存器中接收到的数据给A
CJNE A,#52H,RING3;判断串口数据R
CLR RI;软件清除串口中断标记
LCALL PDRI;等待下一个串口数据
MOV A,SBUF;将串口寄存器中接收到的数据给A
CJNE A,#49H,RING3;判断串口数据I
CLR RI;软件清除串口中断标记
LCALL PDRI;等待下一个串口数据
MOV A,SBUF;将串口寄存器中接收到的数据给A
CJNE A,#4EH,RING3;判断串口数据N
CLR RI;软件清除串口中断标记
LCALL PDRI;等待下一个串口数据
MOV A,SBUF;将串口寄存器中接收到的数据给A
CJNE A,#47H,RING1;判断串口数据G
CLR RI;软件清除串口中断标记
LCALL PDDA;调用串口接收0D/0A数据子程序
MOV DPTR,#100;延时0.1秒
LCALL DelayXmS
;发送AT+CLCC
LCALL CLCC;调用来电显示指令子程序
;跳过20个内存(: 1,1,4,0,0,")
MOV R3,#20;定义接收数据的总长度
LCALL TGSJ;调用跳过数据子程序
MOV R3,#13;定义接收数据的总长度为12个
MOV R0,#44H;数据从内存的44H开始依次往后存放
LCALL GPSSJ;调用接收串口数据子程序
MOV R3,#13;跳过13个数据
LCALL TGSJ;调用跳过串口数据子程序
MOV A,#1 ;显示在第一行
MOV 40H,#"T"
MOV 41H,#"E"
MOV 42H,#"L"
MOV 43H,#":"
MOV R0,#40H
MOV R1,#0
CALL LCD_SHOW;显示来电号码
;检查是否继续呼入
;等待第二次RING电话呼入提示
CLR RI;软件清除串口中断标记
LCALL PDDXRI;5秒内检测串口是否有数据返回?
JNC RING1;如果5秒内没检查到铃音,就退出
;震铃大约22S后进入通话状态
;跳过8个内存
MOV R3,#8;定义接收数据的总长度
LCALL TGSJ;调用接收串口数据子程序
;**********************************************
PDLYT:
;发送AT+CPAS,模块状态报告
MOV R2,#30
ZLYKK1:
MOV DPTR,#500;延时0.5秒
LCALL DelayXmS
LCALL CPAS;调用模块状态报告子程序
MOV A,25H
CJNE A,#30H,ZL1;挂机后会收到2次30,没挂机收到的是33
RET;对方挂机就退出
; AJMP ZLYK;如果没有检测到呼入,就进入振铃遥控
ZL1:
DJNZ R2,ZLYKK1
MOV R2,#15;大约15S后
ZLYKK2:
MOV DPTR,#500;延时0.5秒
LCALL DelayXmS
LCALL CPAS;调用模块状态报告子程序
MOV A,25H
CJNE A,#30H,ZL2
AJMP RING2;如果没有检测到呼入,就退出
ZL2:
DJNZ R2,ZLYKK2;大约22S后应答
;**********************************************
;发送AT+CLCC
LCALL CLCC;调用来电显示指令子程序
;跳过20个内存(: 1,1,4,0,0,")
MOV R3,#20;定义接收数据的总长度
LCALL TGSJ;调用跳过数据子程序
LCALL DHHM;判断来电号码
JZ RING2;号码不对(A==0),就退出
; JZ GJ;号码不对(A==0),则调用挂机子程序
; ;跳过13个内存
; MOV R3,#13;定义接收数据的总长度
; LCALL TGSJ;调用接收串口数据子程序
LCALL ATA;应答
RING1:
AJMP RING2
/* GJ:
MOV DPTR,#500;延时1秒
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -