基于单片机的智能火灾报警系统设计源程序代码分解(共13页).doc
精选优质文档-倾情为你奉上#include <reg52.h> /调用单片机头文件#define uchar unsigned char /无符号字符型 宏定义变量范围0255#define uint unsigned int /无符号整型 宏定义变量范围065535#include <intrins.h>#include "lcd1602.h"#include "eeprom52.h"sbit CS=P24;/CS定义为P2口的第4位脚,连接ADC0832CS脚sbit SCL=P23;/SCL定义为P2口的第3位脚,连接ADC0832SCL脚sbit DO=P22;/DO定义为P2口的第2位脚,连接ADC0832DO脚sbit dq = P20;/18b20 IO口的定义sbit beep = P32; /蜂鸣器IO口定义uint temperature,s_temp ; /温度的变量uchar yanwu,s_yanwu; /烟物等级uchar shoudong; /手动报警键bit flag_300ms ;uchar key_can; /按键值的变量uchar menu_1; /菜单设计的变量bit key_500ms ;uchar phone1_i = 0; /电话号码是多少位uchar phone2_i = 0; /电话号码是多少位uchar phone1_call11=" "uchar phone2_call11=" "uchar dis_smg11;/*1ms延时函数*/void delay_1ms(uint q)uint i,j;for(i=0;i<q;i+)for(j=0;j<120;j+);#include "gsm.h"/*把数组清空*/void clear_shuzu(uchar *p,uchar num)for(i=0;i<num;i+)pi = ' '/*把数据保存到单片机内部eeprom中*写电话号码*/void write_eeprom() /数据保存SectorErase(0x2000);for(i=0;i<11;i+)byte_write(0x2000 + i,phone1_calli);byte_write(0x2012,phone1_i);byte_write(0x2013,phone2_i);byte_write(0x2014, s_temp);byte_write(0x2015,s_yanwu);byte_write(0x2016,a_a);byte_write(0x2020,phone2_call0);byte_write(0x2021,phone2_call1);byte_write(0x2022,phone2_call2);byte_write(0x2023,phone2_call3);byte_write(0x2024,phone2_call4);byte_write(0x2025,phone2_call5);byte_write(0x2026,phone2_call6);byte_write(0x2027,phone2_call7);byte_write(0x2028,phone2_call8);byte_write(0x2029,phone2_call9);byte_write(0x2030,phone2_call10);/*把数据从单片机内部eeprom中读出来*读电话号码*/void read_eeprom()for(i=0;i<11;i+)phone1_calli = byte_read(0x2000+i);phone1_i = byte_read(0x2012);phone2_i = byte_read(0x2013);s_temp = byte_read(0x2014);s_yanwu = byte_read(0x2015);a_a = byte_read(0x2016);phone2_call0 = byte_read(0x2020);phone2_call1 = byte_read(0x2021);phone2_call2 = byte_read(0x2022);phone2_call3 = byte_read(0x2023);phone2_call4 = byte_read(0x2024);phone2_call5 = byte_read(0x2025);phone2_call6 = byte_read(0x2026);phone2_call7 = byte_read(0x2027);phone2_call8 = byte_read(0x2028);phone2_call9 = byte_read(0x2029);phone2_call10 = byte_read(0x2030);/*开机自检eeprom初始化*/void init_eeprom()read_eeprom();/读电话号码if(a_a != 22)a_a = 22;for(i=0;i<11;i+)phone1_calli = ' 'phone2_calli = ' 'phone1_i = 0;phone2_i = 0;s_temp = 50;s_yanwu = 60;write_eeprom(); /保存数据/*18b20初始化函数*/void init_18b20()bit q;dq = 1;/把总线拿高delay_uint(1); /15usdq = 0;/给复位脉冲delay_uint(80);/750usdq = 1;/把总线拿高 等待delay_uint(10);/110usq = dq;/读取18b20初始化信号delay_uint(20);/200usdq = 1;/把总线拿高 释放总线/*写18b20内的数据*/void write_18b20(uchar dat)uchar i;for(i=0;i<8;i+) /写数据是低位开始dq = 0; /把总线拿低写时间隙开始 dq = dat & 0x01; /向18b20总线写数据了delay_uint(5); / 60usdq = 1; /释放总线dat >>= 1;/*读取18b20内的数据*/uchar read_18b20()uchar i,value;for(i=0;i<8;i+)dq = 0; /把总线拿低读时间隙开始 value >>= 1; /读数据是低位开始dq = 1; /释放总线if(dq = 1) /开始读写数据 value |= 0x80;delay_uint(5); /60us读一个时间隙最少要保持60us的时间return value; /返回数据/*读取温度的值 读出来的是小数*/uint read_temp()uint value;uchar low; /在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序init_18b20(); /初始化18b20write_18b20(0xcc); /跳过64位ROMwrite_18b20(0x44); /启动一次温度转换命令delay_uint(50); /500usinit_18b20(); /初始化18b20write_18b20(0xcc); /跳过64位ROMwrite_18b20(0xbe); /发出读取暂存器命令EA = 0;low = read_18b20(); /读温度低字节value = read_18b20(); /读温度高字节EA = 1;value <<= 8; /把温度的高位左移8位value |= low; /把读出的温度低位放到value的低八位中value *= 0.0625; /转换到温度值 return value; /返回读出的温度 /*读数模转换数据*/请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的/ 1 0 0 通道/ 1 1 1 通道 unsigned char ad0832read(bit SGL,bit ODD)unsigned char i=0,value=0,value1=0;SCL=0;DO=1;CS=0;/开始SCL=1;/第一个上升沿SCL=0;DO=SGL;SCL=1; /第二个上升沿SCL=0;DO=ODD;SCL=1; /第三个上升沿DO=1;for(i=0;i<8;i+)SCL=1;SCL=0; /开始从第四个下降沿接收数据value<<=1;if(DO)value+;for(i=0;i<8;i+)/接收校验数据value1>>=1;if(DO)value1+=0x80;SCL=1;SCL=0;CS=1;SCL=1;if(value=value1)/与校验数据比较,正确就返回数据,否则返回0return value;return 0;/*定时器0初始化程序*/void time_init() EA = 1; /开总中断TMOD |= 0X01; /定时器0、定时器1工作方式1ET0 = 1; /开定时器0中断 TR0 = 1; /允许定时器0定时/*独立按键程序*/uchar key_can; /按键值void key() /独立按键程序static uchar key_new = 0, key_l;key_can = 20; /按键值还原P1 = 0x0f;if(P1 & 0x0f) != 0x0f)/按键按下delay_1ms(1); /按键消抖动if(P1 & 0x0f) != 0x0f) && (key_new = 1)/确认是按键按下key_new = 0;key_l = (P1 | 0xf0); /矩阵键盘扫描P1 = key_l;switch(P1)case 0xee: key_can = 1; break; /得到按键值 case 0xde: key_can = 4; break; /得到按键值 case 0xbe: key_can = 7; break; /得到按键值 case 0x7e: key_can = 10; break; /得到按键值 case 0xed: key_can = 2; break; /得到按键值 case 0xdd: key_can = 5; break; /得到按键值 case 0xbd: key_can = 8; break; /得到按键值 case 0x7d: key_can = 0; break; /得到按键值 case 0xeb: key_can = 3; break; /得到按键值 case 0xdb: key_can = 6; break; /得到按键值 case 0xbb: key_can = 9; break; /得到按键值 case 0x7b: key_can = 11; break; /得到按键值 case 0xe7: key_can = 15; break; /得到按键值 case 0xd7: key_can = 14; break; /得到按键值 case 0xb7: key_can = 13; break; /得到按键值 case 0x77: key_can = 12; break; /得到按键值 /write_sfm2(1,0,key_can);else key_new = 1;/*按键处理数码管显示函数*/void key_with()if(key_can = 1) /紧急报警键 手动报警if(menu_1 = 0)shoudong = 1;if(key_can = 12) /退出设置键menu_1 = 0;init_1602() ; /初始化显示if(key_can = 15) /设置键menu_1 +;if(menu_1 >= 5)menu_1 = 0;init_1602() ; /初始化显示if(menu_1 = 3)/输入第一个人的手机号码write_string(1,0," Input Phone 1 ");write_string(2,0," ");clear_shuzu(dis_smg,11); for(i=0;i<phone1_i;i+)dis_smgi = 0x30 + phone1_calli; write_string_num(2,0,dis_smg,phone1_i); /显示号码lcd1602_guanbiao(1,phone1_i + 0x40); /开光标if(menu_1 = 4)/输入第二个人的手机号码write_string(1,0," Input Phone 2 ");write_string(2,0," ");clear_shuzu(dis_smg,11); for(i=0;i<phone2_i;i+)dis_smgi = 0x30 + phone2_calli; write_string_num(2,0,dis_smg,phone2_i); /显示号码lcd1602_guanbiao(1,phone2_i + 0x40); /开光标if(menu_1 = 0)if(key_can = 2) | (key_can = 3)shoudong = 0; /取消手动报警if(menu_1 = 1)/设置高温报警if(key_can = 14)s_temp + ;/高温报警值加1 if(s_temp > 99)s_temp = 99;if(key_can = 13)s_temp - ;/高温报警值减1 if(s_temp <= 10)s_temp = 10 ;write_sfm2(1,8,s_temp); /显示温度write_sfm2(2,8,s_yanwu); /显示烟物等级write_com(0x80+7); /将光标移动到第2行第到3位write_com(0x0f); /显示光标并且闪烁write_eeprom(); /保存数据if(menu_1 = 2)/设置烟物报警if(key_can = 14)s_yanwu + ; /烟物报警值加1 if(s_yanwu >= 99)s_yanwu = 99;if(key_can = 13)s_yanwu -; /烟物报警值减1 if(s_yanwu <= 1)s_yanwu = 1;write_sfm2(1,8,s_temp); /显示温度write_sfm2(2,8,s_yanwu); /显示烟物等级write_com(0x80+0x40+7); /将光标移动到第2行第到3位write_com(0x0f); /显示光标并且闪烁write_eeprom(); /保存数据if(menu_1 = 3)/设置第一个人短信号码 if(key_can < 10) /只有数字键if(phone1_i < 11)phone1_callphone1_i = key_can;dis_smgphone1_i = 0x30 + key_can;phone1_i +;if(phone1_i > 11)phone1_i = 11;write_string_num(2,0,dis_smg,phone1_i); /显示号码lcd1602_guanbiao(1,0 + phone1_i + 0x40); /开光标if(key_can = 11)/删除键if(phone1_i != 0)phone1_i -;phone1_callphone1_i = ' 'dis_smgphone1_i = ' 'write_string(2,0," ");write_string_num(2,0,dis_smg,phone1_i); /显示号码lcd1602_guanbiao(1,0 + phone1_i + 0x40); /开光标 write_eeprom(); /保存数据if(menu_1 = 4)/设置第二个人短信号码 if(key_can < 10) /只有数字键if(phone2_i < 11)phone2_callphone2_i = key_can;dis_smgphone2_i = 0x30 + key_can;phone2_i +;if(phone2_i > 11)phone2_i = 11;write_string_num(2,0,dis_smg,phone2_i); /显示号码lcd1602_guanbiao(1,0 + phone2_i + 0x40); /开光标if(key_can = 11)/删除键if(phone2_i != 0)phone2_i -;phone2_callphone2_i = ' 'dis_smgphone2_i = ' 'write_string(2,0," ");write_string_num(2,0,dis_smg,phone2_i); /显示号码lcd1602_guanbiao(1,0 + phone2_i + 0x40); /开光标 write_eeprom(); /保存数据 /*报警函数*/void clock_h_l()static uchar value,value1;if(yanwu >= s_yanwu) | (temperature >= s_temp) | (shoudong = 1)/报警value +;if(value >= 2)value = 10;beep = beep; /蜂鸣器报警if(value1 = 0)for(i=0;i<6;i+)beep = beep; /蜂鸣器叫3声delay_1ms(100); beep = 1; /关闭蜂鸣器value1 = 1;if(phone1_i = 11) /只有号码输入正确才可以发短信send_PUD_hzbj(); /发送报警信息请注意!火灾报警!for(i=0;i<10;i+)beep = beep; /蜂鸣器叫3声delay_1ms(300); beep = 1; /关闭蜂鸣器if(phone2_i = 11) /只有号码输入正确才可以发短信send_PUD_hzbj(); /发送报警信息请注意!火灾报警!else if(yanwu < s_yanwu) && (temperature < (s_temp) && (shoudong = 0) /取消报警value = 0;beep = 1; /取消报警value1 = 0;/*主函数*/void main()init_1602(); /1602液晶初始化temperature = read_temp(); /读取温度值beep = 0; /开机蜂鸣器叫一声delay_1ms(200);P0 = P1 = P2 = P3 = 0xff; /初始化IO口init_eeprom(); /读eeprom数据time_init();/初始化定时器 init_uart();/串口初始化delay_1ms(650);init_1602(); /1602液晶初始化init_gsm(); /手机模块初始化for(i=0;i<6;i+)beep = beep; /蜂鸣器叫3声delay_1ms(100); beep = 1; /关闭蜂鸣器while(1)key();/独立按键程序if(key_can < 20)key_with();/按键按下要执行的程序if(flag_300ms = 1)flag_300ms = 0;temperature = read_temp(); /读取温度值clock_h_l();yanwu = ad0832read(1,0);yanwu = yanwu * 99 / 255;if(menu_1 = 0)if(temperature >= 99)temperature = 99;write_sfm2(1,8,temperature); /显示温度write_sfm2(2,8,yanwu); /显示烟物等级 /*定时器0中断服务程序*/void time0_int() interrupt 1static uchar value;TH0 = 0x3c;TL0 = 0xb0; / 50msvalue +; if(value % 6 = 0)flag_300ms = 1; /300msvalue = 0;专心-专注-专业