资源描述
(完整word)基于单片机的天然气报警系统资料
基于51单片机天然气报警设计
姓名:李洋
班级:自动化105
学号:2010800091
基于51单片机天然气报警设计
1 设计方案
本文所设计的数字气体报警器采用单片机STC89C52,其价格便宜,易于产品化。本设计能将置于测试环境中的气体传感器输出的模拟电压通过A/D转换器送入单片机STC89C52中进行处理并通过LCD1602液晶进行显示,通过设置报警值,当检测到的浓度达到或者超过设定值时,蜂鸣器出声音报警,来达到报警的目的。
系统以MQ气体传感器和STC89C52 单片机为核心, 设计气体泄漏报警器。实现:
1.准确测量周围环境中的可燃性气体、有毒有害气体的泄漏;
2.实现系统各个模块的功能控制;
3.实现单片机编程语言系统的控制及传感器电路的控制。
4.研究单片机各接口的作用及功能;
5.了解MQ气体传感器的具体功能;
6.实现对基本报警电路的控制.
2 电路设计框图
本系统的电路系统框图如图1所示.STC89C52单片机通过ADC0832对天然气浓度进行读取,继而控制1602液晶作出对应的显示。当天然气浓度高于设定时,蜂鸣器进行报警。
液晶1602显示模块
键盘模块
ADC0832
天然气报警模块模拟量输出
STC89C52
主控制模块
蜂鸣器报警
图1 电路设计框图
3 主要单元电路的设计
3.1核心单片机介绍
STC89C52是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash存储器.STC89C52使用经典的MCS—51内核,但做了很多的改进使得芯片具有传统51单片机不具备的功能.
图2 STC89C52
3.2单片机引脚功能介绍
STC89C52单片机有40个引脚。
Vcc:电源电压+5V
GND:接地
P0口:P0口是一组8位漏极开路型双向I/O口,也即地址/数据总线复用口。作为输出口用时,每位能驱动8个TTL逻辑门电路,对端口写“1"可作为高阻抗输入端用。
在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线服用,在访问期间激活内部上拉电阻。
在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时要求外接上拉电阻.
P1口:P1口是一个带内部上拉电阻的8位双向I/O,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路.对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流。
Flash 编程和程序校验期间,P1接收低8位地址.
P2口:P2口是一个带内部上拉电阻的8位双向I/O,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路.对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流。
在访问外部程序存储器或16位地址的外部数据存储器(例如执行MOVX@DPTR指令)时,P2口送出高8位地址数据.在访问8位地址的外部数据存储器(MOVX @Ri指令)时,P2口线上的内容(也即特殊功能寄存器(SFR)区中P2寄存器的内容),在整个访问期间不改变。
Flash 编程和程序校验期间,P2亦接收低高位地址和其他控制信号。
P3口:P3口是一组带内部上拉电阻的8位双向I/O,P3的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写入“1"时,它们被内部的上拉电阻拉高并可作为输入端口。作输入端时,被外部拉低的P3口将用上拉电阻输出电流。P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能,见表1所示:
P3口还接收一些用于Flash闪速存储器编程和程序校验的控制信号。
端口引脚
第二功能
P3。0
RXD(串行输入口)
P3。1
TXD(串行输出口)
P3。2
INT0(外中断0)
P3.3
INT1(外中断1)
P3.4
T0(定时/计时器0外部输入)
P3。5
T1(定时/计时器1外部输入)
P3。6
WR(外部数据存储器写选通)
P3.7
RD(外部数据存储器读选通)
表1 P3口的第二功能图
RST:复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位.WDT溢出将使引脚输出高电平,设置SFR AUXR的DISRT0(地址8EH)可打开或关闭该功能。DISRT0位缺省为RESET输出高电平打开状态.
ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存器允许)输出脉冲用于锁存地址的低8位字节。即使不访问外部存储器,ALE仍以时钟振荡频率的1/6输出固定的正脉冲信号,因此它可对外输出时钟或用于定时目的。要注意的是:每当访问外部数据存储器时将跳过一个ALE脉冲。
对Flash存储器编程期间,该引脚还用于输入编程脉冲(PROG).
PSEN:程序存储允许(PSEN)输出是外部程序存储器的读选通信号,当STC89C52由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。当访问外部数据存储器,没有两次有效的PSEN信号。
EA/VPP:外部访问允许。欲使CPU仅访问外部程序存储器(地址为0000H-FFFFH),EA端必须保持低电平(接地)。需要注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。
如EA端为高电平(接Vcc端),CPU则执行内部程序存储器中的指令。
Flash存储器编程时,该引脚加上+12V的变成电压Vpp。
XTAL1:振荡器反相放大器及内部时钟发生器的输入端。
XTAL2:振荡器反相放大器的输出端。
看门狗(WDT):WDT是一种需要软件控制的复位方式.WDT 由13位计数器和特殊功能寄存器中的看门狗定时器复位存储器(WDTRST)构成。WDT 在默认情况下无法工作;为了激活WDT,用户必须往WDTRST 寄存器(地址:0A6H)中依次写入01EH 和0E1H。当WDT激活后,晶振工作,WDT在每个机器周期都会增加。WDT计时周期依赖于外部时钟频率。除了复位(硬件复位或WDT溢出复位),没有办法停止WDT工作.当WDT溢出,它将驱动RSR引脚输出一个高电平。
可编程串口(UART)在STC89C52中,UART 的操作与STC89C52 和AT89C52 一样。STC89C52系列单片机的串行通信口可以工作于同步和异步通信方式。当工作于异步方式时,它具有全双工的操作功能,也就是说,它可以同时进行数据的发送和接收。串行口内的接收器采用的是双缓冲结构,能够在接收到的第一个字节从接收寄存器读走之前就开始接收第二个字节(当然,如果第二个字节接收完毕,而第一个字节仍然没有被读走,那将会丢掉一个字节)。串行口的发送和接收操作都是通过特殊功能寄存器中的数据缓冲寄存器SBUF进行的,但在SBUF的内部,接收寄存器和发送寄存器在物理结构上是完全独立的。如果将数据写入SBUF,数据会被送入发送寄存器准备发送.如果执行SBUF指令,则读出的数据一定来自接收缓存器。因此,CPU对SBUF的读写,实际上是分别访问2个不同的寄存器.这2个寄存器的功能决不能混淆.
振荡电路:STC89C52系列单片机的内部振荡器,由一个单极反相器组成。XTAL1反相器的输入,XTAL2为反相器的输出。可以利用它内部的振荡器产生时钟,只要XTAL1和XTAL2引脚上一个晶体及电容组成的并联谐振电路,便构成一个完整的振荡信号发生器,此方式称为内部方式。另一种方式由外部时钟源提供一个时钟信号到XTAL1端输入,而XTAL2端浮空。在组成一个单片机应用系统时,多数采用这种方式,这种方式结构紧凑,成本低廉,可靠性高。在电路中,对电容C1和C2的值要求不是很严格,如果使用高质的晶振,则不管频率为多少,C1、C2通常都选择30pF。
定时/计数器:STC89C52单片机内含有2个16位的定时器/计数器。
RAM:高于7FH内部数据存储器的地址是8位的,也就是说其地址空间只有256字节,但内部RAM的寻址方式实际上可提供384字节。的直接地址访问同一个存储空间,高于7FH的间接地址访问另一个存储空间。
SFR:SFR是具有特殊功能的所有寄存器的集合,共含有22个不同寄存器,它们的地址分配在80H~FFH中。
中断系统:STC89C52单片机有6个中断源,中断系统主要由中断允许寄存器IE、中断优先级寄存器IP、优先级结构和一些逻辑门组成。IE寄存器用于允许或禁止中断;IP寄存器用于确定中断源的优先级别;优先级结构用于执行中断源的优先排序;有关逻辑门用于输入中断请求信号。
3。3其他单元电路设计
A/D转换电路设计
在此用的A/D转换电路中的AD是ADC0832,ADC0832 为8位分辨率A/D转换芯片,其最高分辨可达256级,可以适应一般的模拟量转换要求。其内部电源输入与参考电压的复用,使得芯片的模拟电压输入在0~5V之间。芯片转换时间仅为32μS,据有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。独立的芯片使能输入,使多器件挂接和处理器控制变的更加方便。通过DI 数据输入端,可以轻易的实现通道功能的选择.
天然气传感器
天然气传感器用的是MQ—2烟雾传感器模块。可以用于家庭和工厂的气体泄漏监测装置,适宜于液化气、丁烷、丙烷、甲烷、酒精、烟雾等的探测;它灵敏度可调,工作电压5V 使用前,供电至少预热2分钟以上,传感器稍微发烫属于正常现象,输出形式有模拟量电压输出和数字开关量输出(0和1)。
显示模块设计
设计采用1602液晶显示进行显示,1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
1602LCD 液晶具有如下的特性:
3.3V或5V工作电压,对比度可调。
提供各种控制命令,如:清屏、光标闪烁、显示移位等多种功能.
有80字节显示数据存储器DDRAM。
内建有192个5X7点阵的字型的字符发生器CGROM。
8个可由用户自定义的5X7的字符发生器CGRAM.
按键调整系统模块设计
按键采用3个独立的按键,一个设置键、一个加按键、一个减按键通过这三个按键可以来合理的设置天然气浓度上限的调整。
4 程序流程框图
4.1主程序流程框图
单片机开始执行程序后,首先进行数据初始化,并判断是否高于天然气上限值。如果是,则进行蜂鸣器报警程序;如果否,则进行判断是否需要修改天然气上限值,如果是则就行修改,如果否则进行读取ADC中转化的天然气浓度并且进行数据分离,然后显示直到程序结束。
读取ADC中的天然气浓度转化后的数值
分离天然气浓度并进行显示
显示子程序
返回
开始
判断是否高于天然气上限值?
蜂鸣器报警
是
否
初始化
判断是否要修改天然气上限值?
按键修改上限值
是
否
图3主程序流程框图
4。2 A/D转换流程图
A/D转换时首先进行端口初始化,然后进行通道的选择,然后单片机读取A/D端口的数据,读取完成后,延迟,等待下一个A/D数据的读取。
开始
A/D端口初始化
选择进行转换的通道
读取A/D端口数值
读取完成
返回
图4 A/D主程序流程框图
仿真电路图:
程序源代码:
#include<reg52.h〉
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/******lcd1602显示***********/
uchar tabel[10]="0123456789”;
uchar tabel1[12]="Gas percent:";
uchar tabel2[13]="Set toplimit:”;
uchar temp,i,set_temp,flag;
uchar CH=0x02;
sbit lcden=P1^2;
sbit lcdrs=P1^0;
sbit lcdrw=P1^1;
sbit k1=P3^0;
sbit k2=P3^1;
sbit k3=P3^2;
sbit CS=P1^7; //使能。
sbit CLK=P1^5;//时钟
sbit Do=P1^6; // 数据输出
sbit Di=P1^6;//数据输入
sbit beep=P1^3;//蜂鸣器
uchar A_D(void)
{
uchar i;
uchar data_f=0,data_c=0;
Di=1;
CS=1;
_nop_();
CS=0;
Di=1; //芯片使能之前的初始化。第一个下降沿
CLK=1;
_nop_();
_nop_();
/****************************************/
CLK=0; // 确定通道模式、第2个下降沿
_nop_();
_nop_();
CLK=1;
Di=(bit)(0x02&CH); //设定通道初始化
_nop_();
CLK=0;
_nop_();
_nop_();
CLK=1;
Di=(bit)(0x01&CH); //设定通道初始化 。第3个下降沿
_nop_();
_nop_();
CLK=0; //AD转化的初始化完成。
Di=1;
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
CLK=1;
for(i=8;i〉0;i—-)//得到一个正常排序的8位数据
{
data_f|=Do;
data_f〈〈=1;
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
}
for(i=8;i〉0;i-—)//得到一个反序排列的8位数据
{
data_c<〈=1;
data_c|=Do;
_nop_();
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
}
CLK=0;
_nop_();
_nop_();
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
_nop_();
CLK=1;
_nop_();
CS=1;
_nop_();
_nop_();
data_f=data_f*100/256;
return data_f;
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x—-)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date)
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
lcdrw=0;
lcden=0;
set_temp=20;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
void dispay()
{
if(flag%2==0)
{
write_com(0x80+0x0c);
if(temp/100〉0)
write_data(tabel[(temp/100)]);
delay(20);
write_data(tabel[(temp%100/10)]);
delay(20);
write_data((tabel[(temp%100%10)]));
delay(20);
write_data('%’);
}
write_com(0x80+0x0d+0x40);
write_data(tabel[(set_temp%100/10)]);
delay(20);
write_data((tabel[(set_temp%100%10)]));
delay(20);
write_data(’%');
}
void dispay1()
{
uchar i;
write_com(0x80);
for(i=0;i<12;i++)
write_data(tabel1[i]);
write_com(0x80+0x40);
for(i=0;i〈13;i++)
write_data(tabel2[i]);
}
void keyscan()
{
if(k1==0)
{
delay(10);
if(k1==0)
{
while(!k1);
flag++;
}
}
if(flag%2==1)
{
write_com(0x80+0x0f+0x40);
write_com(0x0e);
if(k2==0)
{
delay(10);
if(k2==0)
{
while(!k2);
set_temp++;
if(set_temp〉=99)
set_temp=99;
}
}
if(k3==0)
{
delay(10);
if(k3==0)
{
while(!k3);
set_temp-—;
if(set_temp〈=0)
set_temp=0;
}
}
}
else
write_com(0x0c);
}
void set_alarm()
{
beep=0;
delay(20);
beep=1;
delay(10);
}
void main()
{
init();
dispay1();
while(1)
{
temp=A_D();
dispay();
keyscan();
if(temp>set_temp)
set_alarm();
}
}
展开阅读全文