基于at89c52的矿井空气检测仪
基于at89c52的矿井空气检测仪
主要功能
1.主控使用at89c52
2.ZPH01检测矿井粉尘浓度
3.MQ-4检测可燃气体浓度
4.通过1602打印出粉尘浓度和可燃气体浓度
5.使用独立按键加减报警阈值
6.使用LED+蜂鸣器来实现声光报警功能
7.使用PCF8591对MQ-4进行AD转换
模块详解
1.ZPH01有两种通讯方式1.PWM模式和2.串口模式
我们这里使用串口模式,将模块的MODE线接地切换到串口模式
波特率为9600,发包格式是
2.MQ-4和PCF8591
MQ-4通过检查空气中的可燃气体浓度来输出对应的电压值,AT89C52中并没有自带的ADC,所以我们用一个PCF8591来实现ADC,PCF8591转换后通过标准的IIC将数据发送给单片机处理
3.报警和阈值
程序中我们分别定义粉尘和可燃气体的报警阈值,可以通过独立按键来进行阈值的修改,当粉尘活可燃气体的浓度到达阈值,蜂鸣器发声警报,同时LED灯闪烁警报
程序
1.iic
void delay()
{_nop_(); //I2C总线使用时一般都要延时5us左右_nop_();
} //================iic==============================================
void init() //初始化总线。将总线都拉高以释放
{scl=1;delay();sda=1;delay();
}void start() //启始信号。 时钟信号为高电平期间,数据总线产生下降沿。
{ //为什么要下降沿,且sda先要为1。因为先要保证数据线为空才能工作sda=1; //先释放数据总线。高电平释放delay();scl=1;delay();sda=0;delay();
}void stop()
{sda=0; //先要有工作状态才能释放,sda=0时在工作状态delay();scl=1;delay();sda=1; //释放数据总线delay();
}void respons() //应答函数
{uchar i=0;scl=1; //每个字节发送完后的第九个时钟信号的开始delay();while((sda==1)&&(i<255)) //此处i的定义使用了uchar.只要填一个小于255的就行i++; //此处的sda是从机的scl=0; //表示主器件默认从器件已经收到而不再等待。不再等待之后,时钟的高电平过了就是低电平,所以scl=0//此时第酒个时钟信号结束
}void writebyte(uchar d) //写一字节,每次左移一位
{uchar i,temp;temp=d;for(i=0;i<8;i++){temp=temp<<1;scl=0; //数据传输期间要想sda可变,先把时钟拉低。此处要给sda赋值delay();sda=CY; //CY为左移移入PSW寄存器中的的CY位。delay();scl=1; //sda有数据了。保持数据稳定delay();}scl=0; //此处是写数据,是属于数据传输过程中。只有在时钟信号为低电平期间delay(); //数据总线才可以变化。sda=1; //所以要想释放数据总线,就必须先把时钟拉低delay(); /*此处释放总线写在末尾是因为调用它时,前面有起始函数释放了总线*/
}uchar readbyte()
{uchar i,k;scl=0;delay();sda=1;delay();/*此处释放总线放在前面是因为一般都是先写后读,保险起见,释放一下总线*/for(i=0;i<8;i++){scl=1; //一个时钟信号的开始delay();k=(k<<1)|sda; //实质是把sda的数据,最先传来的放在最高位,依次往下排scl=0; //一个时钟信号结束delay();}return k;
}
2.LCD1602.c
#include "lcd.h"void lcdinit(void)//lcd1602初始化
{ lcdwrcmd(0x38);lcdwrcmd(0x0c);lcdwrcmd(0x06);lcdwrcmd(0x01);
}
void lcdwrcmd(uchar cmd)//命令写入
{lcdbusy();RS=0;RW=0; DB=cmd;E=1;E=0;
}
void lcdwrdat(uchar dat)//数据写入
{lcdbusy();RS=1;RW=0; DB=dat;E=1;E=0;
}
void lcdbusy(void)//lcd1602忙碌判断
{DB=0xff;RS=0;RW=1;E =1;while(DB&0x80);E=0;
}
void lcdshow(uchar x,uchar y)//显示位置
{ uchar addr;if(1==y){addr=0x00+x;}if(2==y){addr=0x40+x;}lcdwrcmd(addr+0x80);
}
3.LCD1602.h
#ifndef __LCD_H_
#define __LCD_H_
/**********************************
当使用的是4位数据传输的时候定义,
使用8位取消这个定义
**********************************/
//#define LCD1602_4PINS/**********************************
包含头文件
**********************************/
#include<reg52.h>//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif#ifndef uint
#define uint unsigned int
#endif/**********************************
PIN口定义
**********************************/
#define DB P0
sbit E=P2^7;
sbit RW=P2^6;
sbit RS=P2^5;/**********************************
函数声明
**********************************/
/*在51单片机12MHZ时钟下的延时函数*/
//void Lcd1602_Delay1ms(uint c); //误差 0us
///*LCD1602写入8位命令子函数*/
//void LcdWriteCom(uchar com);
///*LCD1602写入8位数据子函数*/
//void LcdWriteData(uchar dat);
///*LCD1602初始化子程序*/
//void LcdInit();
void lcdinit(void); //初始化
void lcdwrcmd(uchar cmd); //命令写入
void lcdwrdat(uchar dat); //数据写入
void lcdbusy(void); //忙碌判断
void lcdshow(uchar x,uchar y); //坐标#endif
4.警报
//=====================警报控制函数==============if((iic_data >= ch4)||(pm25if >= pm25)){bee = 0;fan = 0;flag = 1;} else{ bee = 1;fan = 1;LED = 1;flag = 0;} if(ch4_up_key == 0){delay1ms(5);if(ch4_up_key == 0)while(!ch4_up_key);ch4++;if(ch4 > 99)ch4 = 0; }if(ch4_down_key == 0){delay1ms(5);if(ch4_down_key == 0)while(!ch4_down_key);ch4--;if(ch4 < 0)ch4 = 99; }
LED闪烁我们有定时器来实现
void Timer0Interrupt(void) interrupt 1 //定时器1ms
{TH0 = 0x0FC;TL0 = 0x66;//add your code here!if(flag == 1){timer++;if(timer == 100){timer = 0;LED = ~LED;} }
}
5.ZPH01
lcdinit(); //LCD初始化 SCON = 0x50;TMOD = 0x20; //Set Timer1 as 8-bit auto reload modeTH1 = TL1 = -(FOSC/12/32/BAUD); //Set auto-reload vauleTR1 = 1; //Timer1 start runES = 1; //Enable UART interruptEA = 1;bee = 1;fan = 1;LED = 1;init();//-----中断服务函数---串口接收函数-------
void Uart_Isr() interrupt 4
{if (RI){RI = 0; //Clear receive interrupt flagrec[i1++] = SBUF;if(i1 > 8)i1 = 0; // rec[i1++] = SBUF; //show UART data}if (TI){TI = 0; //Clear transmit interrupt flagbusy = 0; //Clear transmit busy flag}
}
6.主函数
void main() //主函数
{uchar rec1;uchar rec2;char ch4 = 50;int pm25 = 40;uint iic_data;uint iic_data1;uchar i; uchar pm25if;lcdinit(); //LCD初始化 SCON = 0x50;TMOD = 0x20; //Set Timer1 as 8-bit auto reload modeTH1 = TL1 = -(FOSC/12/32/BAUD); //Set auto-reload vauleTR1 = 1; //Timer1 start runES = 1; //Enable UART interruptEA = 1;bee = 1;fan = 1;LED = 1;init();TMOD |= 0x01; //定时器初始化TH0 = 0x0FC;TL0 = 0x66;EA = 1;ET0 = 1;TR0 = 1;while(1){//----------显示CH4----PM2.5--------lcdshow(0,1);for(i = 0;i<6;i++){lcdwrdat(CH4[i]);} lcdshow(0,2);for(i = 0;i<6;i++){lcdwrdat(PM25[i]); }
//------------pm2.5-------------------------lcdshow(6,2);lcdwrdat(rec1/10%10+'0');lcdshow(7,2);lcdwrdat(rec1%10+'0');lcdshow(9,2);lcdwrdat('.');lcdshow(8,2);lcdwrdat(rec2/10%10+'0');lcdshow(10,2);lcdwrdat(rec2%10+'0');//------------ch4------------------------iic_data1 = read(0x40);iic_data = iic_data1*0.35; lcdshow(6,1);lcdwrdat(iic_data/10%10+'0');lcdshow(7,1);lcdwrdat(iic_data%10+'0');lcdshow(8,1);lcdwrdat('%');//=====================警报控制函数==============if((iic_data >= ch4)||(pm25if >= pm25)){bee = 0;fan = 0;flag = 1;} else{ bee = 1;fan = 1;LED = 1;flag = 0;} if(ch4_up_key == 0){delay1ms(5);if(ch4_up_key == 0)while(!ch4_up_key);ch4++;if(ch4 > 99)ch4 = 0; }if(ch4_down_key == 0){delay1ms(5);if(ch4_down_key == 0)while(!ch4_down_key);ch4--;if(ch4 < 0)ch4 = 99; } lcdshow(13,1);lcdwrdat(ch4/10 + '0');lcdshow(14,1);lcdwrdat(ch4%10 + '0');lcdshow(15,1);lcdwrdat('%');
//=============ch4--完 ================== //=========PM25==按键控制警报函数======== if(PM25_up_key == 0){delay1ms(5);if(PM25_up_key == 0)while(!PM25_up_key);pm25++;if(pm25 > 300)pm25 = 0; }if(PM25_down_key == 0){delay1ms(5);if(PM25_down_key == 0)while(!PM25_down_key);pm25--;if(pm25 < 0)pm25 = 300; } lcdshow(13,2);lcdwrdat(pm25/100%10 + '0');lcdshow(14,2);lcdwrdat(pm25/10%10 + '0');lcdshow(15,2);lcdwrdat(pm25%10 + '0');
//========================================if((rec[0] == 0xff)){rec1 = rec[3];rec2 = rec[4];pm25if = (rec[3]%10*10)+(rec[4]/10); }}
}
基于at89c52的矿井空气检测仪相关推荐
- 传感器实训心得体会_基于at89c52传感器实训报告总结
基于at89c52传感器实训报告总结 为了适应公司新战略的发展,保障停车场安保新项目的正常.顺利开展,特制定安保从业人员的业务技能及个人素质的培训计划基于at89c52传感器实训报告总结九江学院信息科 ...
- 基于AT89C52单片机的温湿度检测设计
点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87704704 源码获取 主要内容: ...
- 脉冲时间宽度c语言,基于AT89C52脉冲宽度测量仪的设计与实现
赵翠玉 摘要:本文基于AT89C52的脉冲宽度测量仪的设计.该仪器测量结果采用了软件数字滤波,消除了测量中抖动问题,测量精度高.稳定性好,具有一定的实用性. 关键词:AT89C52;测量仪;脉冲宽度 ...
- 基于AT89C52单片机的数字电压表设计
一.系统组成及工作原理 1.1 系统组成 该基于AT89C52单片机的数字电压表设计由AT89C51单片机,ADC0809芯片(A/D转换器),LED数码管显示电路以及蜂鸣器电路等几部分组成.(用到得 ...
- c语言数字植物管理系统,基于AT89C52单片机的智能浇花系统(包含程序代码)
内容简介: 基于AT89C52单片机的智能浇花系统,毕业论文,共50页,18022字,附程序代码.实物图等. 摘要 伴随着经济的快速发展,人们的物质生活水平得到了极大的提高,生活质量越来越为人们关注. ...
- 基于AT89C52单片机的1602液晶显示程序
基于AT89C52单片机的1602液晶显示程序 1602液晶显示 1.keyscan.c 2.boardinit.c 3.delay.c 4.clock.c 5.74hc595.c 6.1602led ...
- 基于AT89C52和MQ-2的烟雾报警器设计
基于AT89C52和MQ-2的烟雾报警器设计 摘要:介绍了一种基于AT89C52单片机和MQ-2型半导体电阻式烟雾传感器的烟雾报警器设计.该烟雾报警器具有声光报警.浓度显示以及与上位机串口通信等功能. ...
- 基于AT89C52单片机的无线温度监测设计
点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87848530?spm=1001.20 ...
- 【毕业设计】基于单片机的酒驾检测仪 - stm32 物联网 酒精检测
文章目录 0 简介 1 项目简介 2 系统设计 3 硬件设计 3.1 MQ-3 模块 3.2 GPRS模块 4 软件设计 4.1 GPRS模块使用 常用AT指令 4.1.1 数据收发demo 5 实现 ...
最新文章
- archlinux cn源
- 见了很久没见的高中同学,真好
- linux 可执行文件的分析(gcc GUN BUILEIN)
- mysql.h 动态编译命令_Linux环境编译动态库和静态库总结
- 从今天开始学习iOS开发(iOS 7版)-- 构建一款App之App开发过程 (二)
- .Net Framework名词定义
- 贺利坚老师汇编课程39笔记:用于内存寻址的寄存器同时引入BP
- 零基础学习.NET平台和Csharp编程开发
- 调试ST电机库5.20遇到的问题
- python udp socket通信
- ffplay播放摄像头
- 全年营业额怎么计算_个人所得税能不能按全年总收入计算
- qt GraphicsScene添加背景
- 什么是模块化,模块化的好处是
- synchronized和Lock的异同
- Linux 下的zip,rar
- Ruoyi 解释(一)
- idea跑android项目报A problem occurred configuring project ‘:app‘
- Anaconda 大疆 Tello EDU python 环境配置
- STC单片机蓝牙无线下载-烧写程序ISP(STC8 STC15 STC12 STC11 STC89)