暑假終究還是結束了,但是既然開學了那么期末還會遠嗎?然而每當期末總會遇到一些課程設計,我每次總是想要大展拳腳一下,但是面對期末復習,最后更多的是通過為主,所以我整理了一些專案希望可以幫到大家,在文章最后更是附上原理圖以及程式以備不時之需,
本次設計制作的GSM短信防盜報警系統,具有紅外報警功能,就是通過熱釋傳感器檢測是否有人進入并將報警資訊通過GSM模塊發短信到指定手機報警,
按照系統設計功能的要求,確定系統以單片機控制電路為核心由時鐘電路、復位電路、電源電路、按鍵電路、1602顯示電路、GSM模塊電路和傳感器電路共同組成,系統結構框圖如下所示:

經過反復論證(實際上就是便宜簡單)最終確定如下方案:
1.STC89C52單片機作為主控制器,
2.采用熱釋電紅外線傳感器采集資訊,
3.通過1602液晶顯示,
4.矩陣式薄膜按鍵
5.9V電源供電
6.SIM800L GSM模塊報警
一、硬體電路系統設計
1.單片機最小系統設計

注意:由于單片機P0口內部不含上拉電阻,為高阻態,不能正常的輸出高/低電平,因而該組埠在使用時必須外接上拉電阻,
下面對STC89C52各引腳的功能進行的介紹:
1)電源引腳Vcc和Vss
Vcc(40腳):電源端為+5V Vss(20腳):接地端,
2)時鐘電路引腳XTAL1和XTAL2
XTAL2(18腳):接外部晶體和電容的一端,在單片機內部它是振蕩電路反向放大器的輸出端,振蕩電路的頻率就是晶體固有頻率,若需采用外部時針電路時,該引腳輸入外時鐘脈沖,要檢查89C52的振蕩電路是否正常作業,可用示波器查看XTAL2端是否有脈沖信號輸出,
XTAL1(19腳):接外部晶體和微調電容的另一端,在片內,它是振蕩電路反向放大器的輸入端,在采用外部時鐘時,該引腳必須接地,
3)控制信號腳 RST ALE PSEN 和EA,
RST(9腳):RST是復位信號輸入端,高電平有效,在此輸入端保持兩個機器周期(24個時鐘振蕩周期)的高電平時,就可以完成復位操作,
ALE/PROG(30引腳):地址鎖存允許信號端,當STC89C52上電正常作業后,ALE引腳不斷向外輸出正脈沖信號,此頻率為振蕩器頻率fosc的1/6,當CPU訪問片外存盤器時,ALE輸出信號作為鎖存低8位地址的控制信號,在CPU訪問片外資料存盤時,每取值一次(一個機器周期)會丟失一個脈沖,平時不訪問片外存盤時,ALE端也以1/6的振蕩頻率固定輸出正脈沖,因而ALE信號可以用作對外輸出時鐘或定時信號,如果你想看一下STC89C52芯片的好壞,可用示波器查看ALE端是否有脈沖信號輸出,如有脈沖信號輸出,則STC89C52基本上是好的,ALE的負載驅動能力為8個LS型TTL(低功耗高速TTL),
PSEN(29腳);程式存盤允許輸出信號引腳,在訪問片外程式存盤器時,此端定時輸出負脈沖作為讀片外存盤器的選通信號,此引腳接ERROM的OE端,PSEN端有效,即允許讀出ERROM/ROM中的指令碼,CPU在從外部ERROM/ROM取指令期間,每個周期PSEN兩次有效,不過,在訪問片外RAM時,要少產生兩次PSEN負脈沖信號,要檢查一個STC89C52小系統上電后CPU能否正常到ERROM/ROM中讀取指令碼,也可用于示波器看PSEN端有無脈沖輸出,如有,說明基本上作業正常,
EA/VPP(31腳):外部程式存盤器地址允許輸入端/固化編程電壓輸入端,當EA引腳接高電平時,CPU只訪問片內ERROM/ROM并執行內部程式存盤器中的指令,但在PC(程式計數器)的值超過OFFFH(對8751/8051為4k)時,將自動轉向執行片外存盤器的程式,當出入信號EA引腳接低電平(接地)時,CPU只訪問外部ERROM/ROM并執行外部程式存盤器中的指令,而不管是否有片內程式存盤器,對于無芯片內的ROM的8031或8032,須外擴ERROM,此時必須將EA引腳接地,如果使用有片內ROM的AT89C52,外擴ERROM也是可以的,但也要使EA接地,
2.顯示模塊
1602LCD采用標準的14引腳(無背光)或16引腳(帶背光)介面,各引腳介面說明如下表所示:

注意:
第3腳:VL為液晶顯示幕對比度調整端,接正電源時對比度最弱,接地時對比度最高,對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度,
第4腳:RS為暫存器選擇,高電平時選擇資料暫存器、低電平時選擇指令暫存器,
第5腳:R/W為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作,當RS和R/W共同為低電平時可以寫入指令或者顯示地址,當RS為低電平R/W為高電平時可以讀忙信號,當RS為高電平R/W為低電平時可以寫入資料,
第6腳:E端為使能端,當E端由高電平跳變成低電平時,液晶模塊執行命令,
電路如下所示:

3.鍵盤模塊
系統通過薄膜矩陣鍵盤設定,電路圖如圖所示:

4.防盜報警電路
下圖為熱釋防盜報警電路,D3、D4為布防指示燈和傳感器信號指示燈
二、系統軟體設計
單片機系統除了必要的硬體支持外,還需要進行軟體設計,主要由主程式、資料查詢程式、按鍵處理程式等組成,
1.主程式設計
主程式是對整個系統框架的描述,此系統的主程式的功能是在上電后,完成系統的初始化,等待控制端資訊命令的到達,并根據資訊內容完成回應的動作,流程圖如下所示:

2.顯示程式設計:
如圖為LCD1602顯示流程圖

三:原理圖

四:程式
#include <reg52.h>
#include "lcd1602.h"
#define uchar unsigned char
#define uint unsigned int
#include "eepom52.h"
uchar i;
sbit red = P2^0; //紅色發光二極管定義
sbit green = P2^1; //綠色發光二極管定義
sbit yellow = P2^2; //黃色發光二極管定義
sbit beep = P2^3; //蜂鳴器定義
sbit hw = P2^4; //紅外熱釋傳感器定義
bit flag_500ms = 0;
uchar flag_alarm ; //報警標志位
uchar flag_bufang ; //布防標志位
uchar flag_bufang_en ; //布防標志位使能
uint flag_value; //用做定時器的變數
bit flag_alarm_en;
#define key_io P0
uchar key_can;
uchar a_a;
uchar smg_i;
uchar dis_smg[11];
uchar phone_i; //電話號碼是多少位
uchar phone_call[11]={" "};
uchar flag_send_en;
uint temperature ; //
bit flag_500ms ;
uchar key_can; //按鍵值的變數
uchar menu_1; //選單設計的變數
bit flag_lj_en; //按鍵連加使能
bit flag_lj_3_en; //按鍵連3次連加后使能 加的數就越大了
uchar key_time; //用做連加的中間變數
bit key_500ms ;
uchar flag_clock; //溫度報警變數
uchar menu_shudu = 20; //用來控制連加的速度
/***********************1ms延時函式*****************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<110;j++);
}
#include "gsm.h"
/******************把資料保存到單片機內部eepom中******************/
void write_eepom()
{
SectorErase(0x2000);
for(i=0;i<11;i++)
byte_write(0x2000 + i,phone_call[i]);
byte_write(0x2020,phone_i);
byte_write(0x2059, a_a);
}
/******************把資料從單片機內部eepom中讀出來*****************/
void read_eepom()
{
for(i=0;i<11;i++)
phone_call[i] = byte_read(0x2000+i);
phone_i = byte_read(0x2020);
a_a = byte_read(0x2059);
}
/******************初始化eeprom******************/
void init_eeprom() //初始化eeprom
{
read_eepom(); //讀資料eeprom
if(a_a == 0xff) //新的單片機初始單片機內問EEPOM
{
a_a = 1;
phone_i = 0;
write_eepom();
}
}
/*************定時器0初始化程式***************/
void time_init()
{
EA = 1; //開總中斷
TMOD |= 0X01; //定時器0、作業方式1
ET0 = 1; //開定時器0中斷
TR0 = 1; //允許定時器0定時
}
/****************獨立按鍵處理函式************************/
void key()
{
static uchar key_new = 0,key_old = 0,key_value = 0,key_l;
key_io = 0x0f;
if(key_new == 0) //按鍵松開
{
if(key_io == 0x0f)
key_value ++;
else
key_value = 0;
if(key_value >= 5) //按鍵松開松手檢測
{
key_value = 0;
key_new = 1; //按鍵松開后進入等待按鍵狀態
flag_lj_en = 0; //關閉連加使能
flag_lj_3_en = 0; //關閉3秒后使能
flag_value = 0; //清零
write_eepom();
}
}
else
{
if(key_io != 0x0f) //按鍵按下
key_value ++;
else
key_value =0;
if(key_value >= 5) //按鍵按下消抖
{
key_value = 0;
key_new = 0; //按鍵松開后進入等待松開按鍵狀態
key_time = 0;
}
}
key_can = 20;
if((key_new == 0) && (key_old == 1))
{
key_l = (key_io | 0xf0); //矩陣鍵盤掃描
key_io = key_l;
switch(key_io)
{
case 0xee: key_can = 1; break; //得到按鍵值
case 0xde: key_can = 2; break; //得到按鍵值
case 0xbe: key_can = 3; break; //得到按鍵值
case 0x7e: key_can = 15; break; //得到按鍵值
case 0xed: key_can = 4; break; //得到按鍵值
case 0xdd: key_can = 5; break; //得到按鍵值
case 0xbd: key_can = 6; break; //得到按鍵值
case 0x7d: key_can = 14; break; //得到按鍵值
case 0xeb: key_can = 7; break; //得到按鍵值
case 0xdb: key_can = 8; break; //得到按鍵值
case 0xbb: key_can = 9; break; //得到按鍵值
case 0x7b: key_can = 13; break; //得到按鍵值
case 0xe7: key_can = 10; break; //得到按鍵值
case 0xd7: key_can = 0; break; //得到按鍵值
case 0xb7: key_can = 11; break; //得到按鍵值
case 0x77: key_can = 12; break; //得到按鍵值
}
}
key_old = key_new;
}
/****************按鍵處理數碼管顯示函式***************/
void key_with()
{
if(key_can == 12) //退出鍵
{
menu_1 = 0;
init_1602_dis_csf();
write_com(0x0c); //關閉游標
}
if(key_can == 15) //設定鍵
{
menu_1 ++;
if(menu_1 >= 2)
{
menu_1 = 0;
}
if(menu_1 == 0)
{
init_1602_dis_csf();
write_com(0x0c); //關閉游標
}
if(menu_1 == 1)
{
write_string(1,0," Input Phone ");
write_string(2,0," ");
clear_shuzu(dis_smg,11);
for(i=0;i<phone_i;i++)
dis_smg[i] = 0x30 + phone_call[i];
write_string_num(2,0,dis_smg,phone_i); //顯示號碼
lcd1602_guanbiao(1,phone_i + 0x40); //開游標
}
menu_shudu = 20;
}
if(menu_1 == 1) //設定短信號碼
{
if(key_can < 10) //只有數字鍵
{
if(phone_i < 11)
{
phone_call[phone_i] = key_can;
dis_smg[phone_i] = 0x30 + key_can;
phone_i ++;
if(phone_i > 11)
phone_i = 11;
smg_i = phone_i;
write_string_num(2,0,dis_smg,phone_i); //顯示號碼
lcd1602_guanbiao(1,0 + phone_i + 0x40); //開游標
}
}
if(key_can == 10) //洗掉鍵
{
if(phone_i != 0)
{
phone_i --;
phone_call[phone_i] = ' ';
dis_smg[phone_i] = ' ';
write_string(2,0," ");
write_string_num(2,0,dis_smg,phone_i); //顯示號碼
lcd1602_guanbiao(1,0 + phone_i + 0x40); //開游標
}
}
}
}
/******************對應不同按鍵處理**********************/
void menu_kongwai_dis()
{
if(menu_1 == 0)
{
if(key_can == 1) //按鍵緊急報警
{
flag_alarm = 1; //報警標志位 ;
}
if(key_can == 2) //布防按鍵
{
flag_bufang_en = 1;
}
if(key_can == 3) //取消報警 把變數清零
{
flag_alarm = 0;
flag_bufang = 0;
flag_bufang_en = 0;
flag_value = 0;
flag_send_en = 0;
beep = 1;
red = 1; //關閉紅燈
green = 1; //關閉綠燈
yellow = 1; //關倍訓燈
write_string(1,0," fd system ");
write_string(2,0," wei bufang ");
}
}
}
/******************紅外報警處理**********************/
void hongwai_dis() // 紅外報警處理
{
if((flag_alarm == 1)) //報警
{
red = ~red; //紅燈報警
beep = ~beep; //蜂鳴器報警
}
if(menu_1 == 0)
{
if(flag_alarm == 1)
{
if(flag_send_en == 0)
{
flag_send_en = 1;
write_string(1,0," fang dao alarm ");
send_PUD_fangdao(); //發送報警資訊 請注意!溫度報警,
}
}
}
yellow = ~hw; //紅外熱釋電指示燈 有輸出就亮黃燈
if(flag_bufang_en == 1) //準備開始布防
{
green = ~green; //綠燈閃
}
if(flag_bufang == 1) //確認布防
{
green = 0; //如果延時布防成功 綠燈長亮
if(hw == 1) //紅外有輸出
{
flag_alarm = 1;
}
}
if(flag_bufang_en == 1)
{
flag_value ++;
if(flag_value >= 30) //15秒
{
flag_bufang = 1;
flag_bufang_en = 0;
flag_value = 0;
write_string(2,0," yi bufang ");
}
}
}
void main()
{
time_init(); //初始化定時器
init_1602();
init_1602_dis_csf();
init_uart();
init_eeprom(); //初始化eeprom
init_gsm();
while(1)
{
if(flag_500ms == 1) //500ms 處理一次溫度程式
{
flag_500ms = 0;
hongwai_dis(); // 紅外報警處理
}
key(); //按鍵程式
if(key_can < 20)
{
key_with(); //設定報警溫度
menu_kongwai_dis();
}
}
}
/*************定時器0中斷服務程式***************/
void time0_int() interrupt 1
{
static uchar value;
TH0 = 0x3c;
TL0 = 0xb0; // 50ms
value ++;
if(value % 10 == 0)
{
flag_500ms = 1; //500ms
value = 0;
}
}
void uatr0() interrupt 4
{
if(RI == 1)
{
RI = 0;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297916.html
標籤:其他
