本设计由STC89C52单片机电路+L充电602液晶显示电路+A/D采样PCF8591电路+蜂鸣器报警电路+LED指示灯电路+按键电路+MQ-9煤气传感器电路+电源电路组成。
1、LCD1602液晶实时显示当前的煤气浓度显示。
2、当浓度0~200ppm时,绿灯亮,当浓度达到200ppm时,黄灯亮,当浓度达到400ppm时,红灯亮。
3、可以通过按键设置煤气浓度阈值设置范围210-990,当前阈值超过设置阈值蜂鸣器报警。
4、当前阈值超过设置阈值,GSM模块向手机发送短信“Dangerous!”否则,不发送短信。
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#include"delay.h"
#include "i2c.h"
#include "1602.h"
sbit key1 =P1^0; //接口定义
sbit key2 =P1^1;
sbit key3 =P1^2;
sbit led_red =P1^5; //接口定义
sbit led_gre =P1^6;
sbit led_yel =P1^7;
sbit buzzer =P1^4;
sbit LED=P2^2;
bit rekey =0;//防止重复按下
unsigned long time_20ms=0; //定时计数
unsigned char i;
unsigned char dis0[16];//串口数据暂存
unsigned int nongDu = 0; //浓度
unsigned int setNd = 300; //设置浓度
bit disFlag = 0;//显示标志
char Crtl_Z[1]={0x1a}; //发送短信最后字节
unsigned int ReportLater = 5 ; //上报计数
void Init_Timer0(void);//函数命令
void UART_Init(void);
void uartSendByte(unsigned char dat);
void uartSendStr(unsigned char *s,unsigned char length);
void main (void)
{
Init_Timer0(); //定时器0初始化
UART_Init(); //串口初始化
LED=0; //打开led
for(i=0;i<50;i++)
{DelayMs(100);}
uartSendStr("AT+CMGF=1\r\n",11); //设置字符
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏
sprintf(dis0,"nd:%03dppm ",nongDu);//显示浓度
LCD_Write_String(0,0,dis0);//显示时间及温度
LCD_Write_String(0,1,"0-200-400-max");//显示
LED=1; //关闭 led
while(1) //主循环
{
if((key1==0)||(key2==0)) //检测到按键按下
{
if(rekey == 0)//防止重复按下
{
DelayMs(20);
}
}
else
{rekey =0 ;} //防止重复按下
if(disFlag==1)
{
disFlag=0;
nongDu=(long)ReadADC(0)*999/255; //计算出电压 *5表示分压值
sprintf(dis0,"nd:%03dppm %03d ",nongDu ,setNd );//显示浓度
LCD_Write_String(0,0,dis0);//显示时间及温度
LCD_Write_String(0,1,"0-200-400-max");//显示
else //只有红灯亮
{
led_gre = 1;
led_yel = 1;
led_red = 0;
}
if(nongDu > setNd)
{
buzzer = 0;//打开蜂鸣器
if(ReportLater > 20)
{
LED=0; //打开led
uartSendStr("AT+CMGF=1\r\n",11);
for(i=0;i<7;i++)
DelayMs(100); //延时有助于稳定
uartSendStr("AT+CSCS=\"GSM\"\r\n",15);
for(i=0;i<7;i++)
DelayMs(100); //延时有助于稳定
// uartSendStr("AT+CMGS=\"+8618105140357\"\r\n",26); //可以修改电话号码
uartSendStr("AT+CMGS=\"+8618139132556\"\r\n",26); //可以修改电话号码
DelayMs(100); //延时有助于稳定
uartSendStr( (unsigned char *)Crtl_Z, 1); //发送
for(i=0;i<20;i++)
DelayMs(100); //延时有助于稳定
ReportLater=0;
LED=1; //关闭 led
}
}
else
{
buzzer = 1;//关闭蜂鸣器
}
}
}
}
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TL1 = TH1;
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void uartSendByte(unsigned char dat)
{
unsigned char time_out;
time_out=0x00;
SBUF = dat; //将数据放入SBUF中
while((!TI)&&(time_out<100)) //检测是否发送出去
{time_out++;DelayUs2x(10);} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
void uartSendStr(unsigned char *s,unsigned char length)
{
unsigned char NUM;
NUM=0x00;
while(NUM<length) //发送长度对比
{
uartSendByte(*s); //放松单字节数据
s++; //指针++
NUM++; //下一个++
}
}
void Timer0_isr(void) interrupt 1
{
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
time_20ms++;
if(time_20ms % 20==0)
{
disFlag=1;
ReportLater++;
}
}
void UART_SER (void) interrupt 4 //串行中断服务程序
{
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
}
if(TI) //如果是发送标志位,清零
TI=0;
}