基于C51单片机的烟雾检测系统 设计与实现

基于C51单片机的烟雾检测系统 设计与实现

天师–大三期末大作业

A/D转换器即实现模拟信号到数字信号的转换,一定要注意周期,即ClK的变化,每一个上升沿会读取次内容
LCD1602显示器即通过7–14位管脚进行内容设置,注意:可以了解图的显示,它是按照坐标形式设置内容(可以搜索查看下),只能显示英文字符
烟雾传感器用滑动变阻器代替,因为protetus中没有MQ-2烟雾感应器,因此用滑动变阻器代替

参考1A/D转换器
参考2A/D转换器
参考3单片机网课

大作业思路:A/D转换器,每个上升沿会读取内容,同时LCD显示器主要思路类似于计算机组成原理中的数据显示,可以学习下,B站有挺多网课

在这里插入图片描述

#include <reg51.h>//包含51单片机寄存器的头文件
#include <wyb.h>//
#include <intrins.h> 
#define uchar unsigned char
#define uint unsigned int
	
//ADC0832引脚定义
sbit CS = P1^0;//片选使能位,定义为P1^0引脚
sbit CLK = P1^1;//时钟脉冲输入位,定义为P1^1引脚
sbit DIO = P1^2;//数据信号输入/输出,并联使用。定义为P1^2引脚
//有害气体含量变量
uchar temp;			     //用于读取ADC数据
uchar yushe_yanwu= 230;	 //烟雾预设值7

//按钮模式 
uchar mode=0;	
//管脚声明
sbit led_yanwu= P2^3;		 //烟雾报警灯
sbit baojing= P2^4;			 //蜂鸣器接口

//按键
sbit key1=P2^5;				 //设置键
sbit key2=P2^6;				 //加按键
sbit key3=P2^7;				 //减按键
//1毫秒延时程序(不精确)
void delayms(uint ms)
{
	uchar t;
	while(ms--)
	{
		for(t=0;t<120;t++);}
}
//ADC0832函数
uchar AD()
{
	uchar i,dat1 = 0,dat2 = 0;
	//第一个周期:转换开始
	CS = 0;
	CLK = 0;
	DIO = 1; 
	_nop_(); _nop_();//短暂定时2us——也可以写成delay2us();,那么程序就要有delay2us();的定义了。
	CLK = 1; _nop_(); _nop_();
	//第二个周期:选择选择单通道还是双通道  DIO=0双通道差分 或 DIO=1单通道
	CLK = 0; DIO=1; _nop_();_nop_();
	CLK = 1;        _nop_();_nop_();
	//第三个周期:DIO选择CH1-->如果DIO=0 选择CH0
	CLK = 0;DIO = 0; _nop_();_nop_();
	CLK = 1;DIO = 1; _nop_();_nop_();
	//等待
	CLK = 0; DIO = 1; _nop_();_nop_();
	//4-11,共8个下降沿读取数据(MSB->LSB) 先进来的为最高位,后进来为最低位
	for(i=0;i<8;i++)
	{
CLK = 1;  _nop_();_nop_();
		CLK = 0;  _nop_();_nop_();
		dat1 = dat1<<1|DIO;
	}
	//11-18 共8个下降沿读取数据(LSB->MSB) 先进来的为最低位,后进来为最高位
	for(i=0;i<8;i++)
	{
		dat2 = dat2|((uchar)(DIO)<<i);
		CLK = 1;  _nop_();_nop_();
		CLK = 0;  _nop_();_nop_();
	}
	CS = 1;
	return (dat1==dat2) ? dat1 : 0 ;	
}

//按键选择程序
void key()
{
	//确定键
	if(key1==0) 
	{
		while(key1==0); 
		if(mode>=2) mode=0;
		else
		{
			writecmd(0x0f); 
			mode++;
			switch(mode)
			{
				case 1 : 
					writecmd(0x80+5);break; 
				case 2 : 
					writecmd(0x0c);mode=0;break; 
			}
		}
    }
	//加键
	if(key2==0&&mode!=0)
	{
		while(key2==0); 
		yushe_yanwu++;
		if(yushe_yanwu>=255) yushe_yanwu=255;
        writecmd(0x80+7); 
		writedata(0x30+yushe_yanwu/100); 
		writedata(0x30+yushe_yanwu%100/10); 
		writedata(0x30+yushe_yanwu%10); 
	}
	//减键
	if(key3==0&&mode!=0)
	{
		while(key3==0); 
		yushe_yanwu--;
        if(yushe_yanwu<=0) yushe_yanwu=0;
		writecmd(0x80+7);   
		writedata(0x30+yushe_yanwu/100); 
		writedata(0x30+yushe_yanwu%100/10); 
		writedata(0x30+yushe_yanwu%10); 
	}
}		
//主程序
void main()
  {
	 init();
	 while(1)
	 {
		 temp=AD();
		 key();
		 if(mode==0)
		 {
			 display_1602(yushe_yanwu,temp); 
			 if(temp>=yushe_yanwu) 
			 {
				 led_yanwu=1; 
				 baojing=1; 
				 baojing=0; 
		     }
			 if(temp<yushe_yanwu) 
			 {
				 led_yanwu=0;
				 baojing=0; 
			 }		
		  }
	  }
   }

//wyb.h文件
#include <reg51.h> 
#include <intrins.h> 
#define uchar unsigned char
#define uint unsigned int
sbit RS = P2^0; 
sbit RW = P2^1; 
sbit EN = P2^2; 
uchar table1[]="SET  E:000 mg/L";
uchar table2[]="NONGDU:000 mg/L";
//判断液晶是否忙碌
void busy()
{
	uchar sta;
	P0= 0xFF; 
	RS = 0; 
	RW = 1; 
	do 
	{
		EN = 1;
		_nop_();
		sta = P0; 
		EN = 0;
	} while (sta & 0x80);
}
// 向 LCD1602 液晶写入一字节命令(8位命令), cmd-待写入命令值 
void writecmd(unsigned char cmd)
{
	busy();
	RS = 0; 
	RW = 0; 
	P0 = cmd; 
	EN = 1;
    _nop_();
	_nop_();
	EN = 0;
}
//向 LCD1602 液晶写入一字节数据(8位数据), dat-待写入数据值 
void writedata(unsigned char dat)
{
	busy();
	RS = 1; 
	RW = 0; 
	P0= dat;
	EN = 1;
	_nop_();
	_nop_();	
	EN = 0;
}
//初始化 1602 液晶 
void init()
{
	uchar i=0; 
	writecmd(0x38); 
	writecmd(0x0C); 
	writecmd(0x06);
	writecmd(0x01); 
	writecmd(0x80); 
	for(i=0;i<16;i++)
	{
		writedata(table1[i]); 
	}	
	writecmd(0x80+0x40); 
	for(i=0;i<16;i++)
	{		
		writedata(table2[i]);
	}
}

//1602显示函数
void display_1602(yushe_yanwu,temp)
{
	writecmd(0x80+7); 
	writedata(0x30+yushe_yanwu/100); 
	writedata(0x30+yushe_yanwu%100/10);
	writedata(0x30+yushe_yanwu%10);
	writecmd(0x80+0x40+7); 
	writedata(0x30+temp/100); 
	writedata(0x30+temp%100/10);
	writedata(0x30+temp%10);
}

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值