【毕业设计】30-基于单片机矿井瓦斯/气体浓度/烟雾浓度报警设计(原理图+源代码+仿真+答辩论文+答辩PPT)
文章目录
- 【毕业设计】30-基于单片机矿井瓦斯/气体浓度/烟雾浓度报警设计(原理图+源代码+仿真+答辩论文+答辩PPT)
- 任务书
- 设计说明书
- 摘要
- 设计框架架构
- 设计说明书及设计文件
- 源码展示
任务书
研究内容:
瓦斯等可燃危险气体的浓度检测是保证煤矿安全生产的重要前提。利用单片机智能控制技术设计一种瓦斯检测系统对矿井瓦斯浓度自动进行实时监测,并在超过安全值时报警。
研究方法:
本次矿井瓦斯浓度检测系统设计以单片机为控制核心,由气体传感器电路、显示电路、报警电路等电路模块组成硬件电路,编制相关控制软件,实现矿井瓦斯气体的浓度进行实时监测,并在超过安全值时报警。
要求:
1、对矿井瓦斯浓度检测系统进行系统结构总体设计;
2、设计瓦斯浓度检测系统的硬件电路;
3、编写瓦斯浓度检测的软件实现程序,并对电路进行仿真研究。
资料链接
1.原理图
2.仿真工程
3.源代码
4.原理图截图
5.仿真截图
6.答辩论文
7.答辩PPT
设计说明书
摘要
本设计第一章主要讲述了矿井瓦斯气体浓度检测系统设计的现状、通过对于目前社会中使用的气体检测系统的使用调查、功能介绍、以及对于当前气体检测的看法、气体使用过程中遇到的问题。针对与目前对于气体检测系统的使用场景分析。第二章主要讲述了矿井瓦斯气体浓度检测系统设计的设计与实现方案分析,是否可以满足目前设计的要求,根据设计要求来对元器件选型,驱动电路选择。绘制出大概的设计框架。第三章主要讲述了矿井瓦斯气体浓度检测系统设计的硬件设计,分别对单片机的最小系统;按键模块、报警模块、LCD1602显示模块、蜂鸣器模块、ADC采集模块、LED显示模块电路原理讲解、析,最后并对整个电路进行了总结。第四章主要讲述了矿井瓦斯气体浓度检测系统设计的软件设计,编程软件Keil进行了详细的介绍,编写单个模块的程序流程,通过流程图来对程序编写,按键模块、报警模块、LCD1602显示模块、蜂鸣器模块、ADC采集模块、LED显示模块程序。第五章主要讲述了矿井瓦斯气体浓度检测系统设计的仿真实现,通过Proteus软件对系统仿真,并验证所设计的功能是否满足要求。
设计框架架构
前 言 1
第一章 绪论 2
第一节 研究背景 2
第二节 研究意义 3
第三节 研究现状 3
第四节 本文的主要研究内容 4
第五节 本章小结 4
第二章 矿井瓦斯气体浓度检测系统设计方案分析 6
第一节 气体传感器介绍 6
一、气体传感器原理 6
二、气体传感器分类 6
第二节 系统设计方案需求 7
第三节 系统结构总框图 8
第四节 本章小结 9
第三章 矿井瓦斯气体浓度检测系统设计硬件电路设计 10
第一节 单片机最小系统模块设计 10
一、单片机的简介 10
二、复位电路设计 11
三、晶振电路设计 11
第二节 气体传感器电路设计 12
第三节 按键电路设计 13
第四节 LED显示电路设计 13
第五节 LCD液晶显示电路设计 14
第六节 蜂鸣器报警电路设计 15
第七节 系统总电路图 16
第八节 本章小结 16
第四章 矿井瓦斯气体浓度检测系统设计的软件设计 18
第一节 Keil软件介绍 18
第二节 软件总设计 18
第三节 按键模块程序设计 19
第四节 LED显示及蜂鸣器模块程序设计 20
第五节 LCD液晶显示模块程序设计 21
第六节 气体传感器模块程序设计 22
第七节 本章小结 23
第五章 瓦斯气体浓度检测系统的仿真 24
第一节 仿真软件介绍 24
第二节 功能仿真并分析 24
一、仿真总电路 24
二、系统功能仿真 25
第三节 本章小结 30
结 论 32
致 谢 33
参考文献 34
附 录 36
一、英文原文 36
二、英文翻译 38
三、工程图纸 40
四、源程序 41
设计说明书及设计文件
源码展示
#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "intrins.h"
#define u8 unsigned char
#define u16 unsigned int
#define uchar unsigned char
#define uint unsigned int
uchar yushe_yanwu=100; //瓦斯预设值
uchar yanwu; //用于读取ADC数据
//运行模式
uchar Mode=0; //=1是设置温度阀值 =2是设置瓦斯阀值 =0是正常监控模式
//管脚声明
sbit Led_Reg =P2^2; //红灯
sbit Led_Yellow =P2^4; //黄灯
sbit Buzzer =P2^0; //蜂鸣器
sbit Fan =P3^3; //
/********************************************************************
* 名称 : delay_1ms()
* 功能 : 延时1ms函数
* 输入 : q
* 输出 : 无
***********************************************************************/
void delay_ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<110;j++);
}
/***********************************************************************************************************
LCD1602相关函数
***********************************************************************************************************/
//LCD管脚声明 (RW引脚实物直接接地,因为本设计只用到液晶的写操作,RW引脚一直是低电平)
sbit LCDRS = P2^7;
sbit LCDEN = P2^6;
sbit D0 = P0^0;
sbit D1 = P0^1;
sbit D2 = P0^2;
sbit D3 = P0^3;
sbit D4 = P0^4;
sbit D5 = P0^5;
sbit D6 = P0^6;
sbit D7 = P0^7;
//LCD延时
void LCDdelay(uint z) //该延时大约100us(不精确,液晶操作的延时不要求很精确)
{
uint x,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
void LCD_WriteData(u8 dat)
{
if(dat&0x01)D0=1;else D0=0;
if(dat&0x02)D1=1;else D1=0;
if(dat&0x04)D2=1;else D2=0;
if(dat&0x08)D3=1;else D3=0;
if(dat&0x10)D4=1;else D4=0;
if(dat&0x20)D5=1;else D5=0;
if(dat&0x40)D6=1;else D6=0;
if(dat&0x80)D7=1;else D7=0;
}
//写命令
void write_com(uchar com)
{
LCDRS=0;
LCD_WriteData(com);
// DAT=com;
LCDdelay(5);
LCDEN=1;
LCDdelay(5);
LCDEN=0;
}
//写数据
void write_data(uchar date)
{
LCDRS=1;
LCD_WriteData(date);
// DAT=date;
LCDdelay(5);
LCDEN=1;
LCDdelay(5);
LCDEN=0;
}
/*------------------------------------------------
选择写入位置
------------------------------------------------*/
void SelectPosition(unsigned char x,unsigned char y)
{
if (x == 0)
{
write_com(0x80 + y); //表示第一行
}
else
{
write_com(0xC0 + y); //表示第二行
}
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
SelectPosition(x,y) ;
while (*s)
{
write_data( *s);
s ++;
}
}
//========================================================================
// 函数: void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l)
// 应用: LCD_Write_Char(0,1,366,4) ;
// 描述: 在第0行第一个字节位置显示366的后4位,显示结果为 0366
// 参数: x:行,y:列,s:要显示的字,l:显示的位数
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注: 最大显示65535
//========================================================================
void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l)
{
SelectPosition(x,y) ;
if(l>=5)
write_data(0x30+s/10000%10); //万位
if(l>=4)
write_data(0x30+s/1000%10); //千位
if(l>=3)
write_data(0x30+s/100%10); //百位
if(l>=2)
write_data(0x30+s/10%10); //十位
if(l>=1)
write_data(0x30+s%10); //个位
}
/*1602指令简介
write_com(0x38);//屏幕初始化
write_com(0x0c);//打开显示 无光标 无光标闪烁
write_com(0x0d);//打开显示 阴影闪烁
write_com(0x0d);//打开显示 阴影闪烁*/
//1602初始化
void Init1602()
{
uchar i=0;
write_com(0x38);//屏幕初始化
write_com(0x0c);//打开显示 无光标 无光标闪烁
write_com(0x06);//当读或写一个字符是指针后一一位
write_com(0x01);//清屏
}
void Display_1602(yushe_yanwu,temp)
{
//显示预设温度
//显示预设瓦斯
LCD_Write_Char(0,13,yushe_yanwu,3) ;
//时时瓦斯
LCD_Write_Char(1,13,temp,3) ;
}
/***********************************************************************************************************
ADC0832相关函数
***********************************************************************************************************/
sbit ADCS =P1^5; //ADC0832 片选
sbit ADCLK =P1^2; //ADC0832 时钟
sbit ADDI =P1^3; //ADC0832 数据输入 /*因为单片机的管脚是双向的,且ADC0832的数据输入输出不同时进行,
sbit ADDO =P1^3; //ADC0832 数据输出 /*为节省单片机引脚,简化电路所以输入输出连接在同一个引脚上
//========================================================================
// 函数: unsigned int Adc0832(unsigned char channel)
// 应用: temp=Adc0832(0);
// 描述: 读取0通道的AD值
// 参数: channel:通道0和通道1选择
// 返回: 选取通道的AD值
// 版本: VER1.0
// 日期: 2015-05-29
// 备注:
//========================================================================
unsigned int Adc0832(unsigned char channel)
{
uchar i=0;
uchar j;
uint dat=0;
uchar ndat=0;
uchar Vot=0;
if(channel==0)channel=2;
if(channel==1)channel=3;
ADDI=1;
_nop_();
_nop_();
ADCS=0;//拉低CS端
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿1
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=channel&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿2
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=(channel>>1)&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿3
ADDI=1;//控制命令结束
_nop_();
_nop_();
dat=0;
for(i=0;i<8;i++)
{
dat|=ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
dat<<=1;
if(i==7)dat|=ADDO;
}
for(i=0;i<8;i++)
{
j=0;
j=j|ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
j=j<<7;
ndat=ndat|j;
if(i<7)ndat>>=1;
}
ADCS=1;//拉低CS端
ADCLK=0;//拉低CLK端
ADDO=1;//拉高数据端,回到初始状态
dat<<=8;
dat|=ndat;
return(dat); //return ad data
}