基于单片机的智能火灾报警系统设计源程序代码

更新时间:2024-06-30 18:38:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

#include //调用单片机头文件

#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255 #define uint unsigned int //无符号整型 宏定义 变量范围0~65535

#include #include \#include \

sbit CS=P2^4; //CS定义为P2口的第4位脚,连接ADC0832CS脚 sbit SCL=P2^3; //SCL定义为P2口的第3位脚,连接ADC0832SCL脚 sbit DO=P2^2; //DO定义为P2口的第2位脚,连接ADC0832DO脚

sbit dq = P2^0; //18b20 IO口的定义 sbit beep = P3^2; //蜂鸣器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_call[11]={\ %uchar phone2_call[11]={\ %uchar dis_smg[11];

/***********************1ms延时函数*****************************/ void delay_1ms(uint q) { uint i,j; for(i=0;i

#include \

/***************把数组清空**********************/ void clear_shuzu(uchar *p,uchar num)

{ for(i=0;i

/******************把数据保存到单片机内部eeprom中**写电话号码****************/ void write_eeprom() //数据保存 { SectorErase(0x2000); for(i=0;i<11;i++) byte_write(0x2000 + i,phone1_call[i]); 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_call[0]); byte_write(0x2021,phone2_call[1]); byte_write(0x2022,phone2_call[2]); byte_write(0x2023,phone2_call[3]); byte_write(0x2024,phone2_call[4]); byte_write(0x2025,phone2_call[5]); byte_write(0x2026,phone2_call[6]); byte_write(0x2027,phone2_call[7]); byte_write(0x2028,phone2_call[8]); byte_write(0x2029,phone2_call[9]); byte_write(0x2030,phone2_call[10]); }

/******************把数据从单片机内部eeprom中读出来**读电话号码***************/ void read_eeprom() { for(i=0;i<11;i++) phone1_call[i] = 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_call[0] = byte_read(0x2020); phone2_call[1] = byte_read(0x2021); phone2_call[2] = byte_read(0x2022);

phone2_call[3] = byte_read(0x2023); phone2_call[4] = byte_read(0x2024); phone2_call[5] = byte_read(0x2025); phone2_call[6] = byte_read(0x2026); phone2_call[7] = byte_read(0x2027); phone2_call[8] = byte_read(0x2028); phone2_call[9] = byte_read(0x2029); phone2_call[10] = byte_read(0x2030); }

/**************开机自检eeprom初始化*****************/ void init_eeprom() { read_eeprom();//读电话号码 if(a_a != 22) { a_a = 22; for(i=0;i<11;i++) { phone1_call[i] = ' '; phone2_call[i] = ' '; } 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); //15us dq = 0; //给复位脉冲 delay_uint(80); //750us dq = 1; //把总线拿高 等待 delay_uint(10); //110us q = dq; //读取18b20初始化信号 delay_uint(20); //200us dq = 1; //把总线拿高 释放总线

}

/*************写18b20内的数据***************/ void write_18b20(uchar dat) { uchar i; for(i=0;i<8;i++) { //写数据是低位开始 dq = 0; //把总线拿低写时间隙开始 dq = dat & 0x01; //向18b20总线写数据了 delay_uint(5); // 60us dq = 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(); //初始化18b20 write_18b20(0xcc); //跳过64位ROM write_18b20(0x44); //启动一次温度转换命令 delay_uint(50); //500us init_18b20(); //初始化18b20

write_18b20(0xcc); //跳过64位ROM write_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) //与校验数据比较,正确就返回数据,否则返回0 return value; return 0; }

/*************定时器0初始化程序***************/ void time_init() { EA = 1; //开总中断 TMOD |= 0X01; //定时器0、定时器1工作方式1 ET0 = 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,\ \ write_string(2,0,\ \ clear_shuzu(dis_smg,11); for(i=0;i

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_call[phone1_i] = key_can; dis_smg[phone1_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_call[phone1_i] = ' '; dis_smg[phone1_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_call[phone2_i] = key_can; dis_smg[phone2_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_call[phone2_i] = ' '; dis_smg[phone2_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 1 { static uchar value; TH0 = 0x3c; TL0 = 0xb0; // 50ms value ++; if(value % 6 == 0) { flag_300ms = 1; value = 0; } }

//300ms

本文来源:https://www.bwwdw.com/article/sgu3.html

Top