?? 家庭無線報警系統.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 + -