基于51单片机酒精浓度检测仪设计

1、设计需求及目标

 本产品采用单片机+最小系统+LCD1602液晶显示模块+MQ-3模块+ADC0832模块+蜂鸣器模块+LED指示灯模块+按键模块设计而成。

(1)采用MQ-3酒精传感器采集酒精浓度,AD0832模数转换芯片将MQ-3酒精传感器采集到的的电压信号转换成数字信号给单片机。
(2)采用LCD1602液晶屏显示当前酒精浓度值和报警值,可以按键设置报警值。
(3)四个按键设置、加、减,单独的是复位按键。
(4)当酒精浓度没有超过设置的阀值时,绿灯闪亮,当酒精浓度超过上限值时,红灯闪烁同时蜂鸣器报警。

2、设计思路及方案

基于51单片机酒精浓度检测仪设计_第1张图片

3、硬件电路

基于51单片机酒精浓度检测仪设计_第2张图片

4、部分代码

//程序头函数
#include 
#include 	//包含头文件
//显示函数
#include 
#include "eeprom52.h"

//宏定义
#define uint unsigned int 
#define uchar unsigned char
 
//管脚声明
sbit LED_R= P2^2;			  //红色指示灯
sbit LED_G= P2^0;			  //绿色指示灯
sbit FENG = P2^5;			  //蜂鸣器
sbit CS   = P1^4;
sbit Clk = P1^2;
sbit DATI = P1^3;
sbit DATO = P1^3;			//ADC0832引脚
//按键
sbit Key1=P2^6;
sbit Key2=P2^7;
sbit Key3=P3^7;
/*******************************定义全局变量********************************/
unsigned char dat = 0;      //AD值
unsigned char CH=0;       //通道变量
unsigned int sum=0;			 //平均值计算时的总数
unsigned char m=0;
bit bdata flag;				  //定义位变量
uchar set;					  //设置变量
uchar   K_ZERO=40;       //传感器零点漂移,约130mV


//函数声明
extern void Key();
/*
void delay(uint z)
{
	uint i,j;
	for(i=0;i>= 1;
		if (DATO)
		test |= 0x80;
		else 
		test |= 0x00;
		_nop_();
		Clk = 1;
		_nop_();
		Clk = 0;
	}
	if (adval == test)      //比较前8位与后8位的值,如果不相同舍去。若一直出现显示为零,请将该行去掉
	dat = test;
	nop_();
	CS = 1;        //释放ADC0832
	DATO = 1;
	Clk = 1;
	return dat;
}

void init()				//定时器初始化函数
{
	TMOD=0x01;			//定时器工作方式
 	TL0=0xb0;
 	TH0=0x3c;			//赋初值50ms
 	EA=1;				//打开中断总开关
	ET0=1;				//打开定时器0中断允许开关
 	TR0=1;				//打开定时器0定时开关
}

void AlcoholCalibration(void)     //酒精初始化校准函数
{
	sum = 0;
	for(m=0;m<50;m++)			//读50次AD值
	{
				sum = adc0832(0)+sum;		//读到的AD值,将读到的数据累加到sum
	}
	temp=sum/50;				//跳出上面的for循环后,将累加的总数除以50得到平均值temp
	K_ZERO = 500 * temp / 256;        //8位ADC,首先得到电压值,单位10毫伏
	Display_1602(0,WARNING);	 //显示AD数值和报警值
}

void main()				//主函数
{
	Init1602();						 //初始化液晶函数
	init();							 //初始化定时器
	init_eeprom();  //开始初始化保存的数据
	while(1)						 //进入循环
	{
		for(m=0;m<50;m++)			//读50次AD值
		sum = adc0832(0)+sum;		//读到的AD值,将读到的数据累加到sum
		temp=sum/50;				//跳出上面的for循环后,将累加的总数除以50得到平均值temp
		if (temp > K_ZERO) 
				temp = temp - K_ZERO;              //首先减去零点漂移,一般是130mV
		else
				temp= 0; 
		sum=0; 						//平均值计算完成后,将总数清零
		if(set==0)					 //set为0,说明现在不是设置状态
		Display_1602(temp,WARNING);	 //显示AD数值和报警值
		if(tempWARNING&&set==0)//AD值大于报警值
		{
			flag=1;					 //打开报警
		}
		Key();						 //调用按键函数
	}
}

void Key()					  //按键函数
{
	if(Key1==0)				  //设置键按下
	{
		while(Key1==0);		  //按键松开
		FENG=0;				  //蜂鸣器响
		set++;				  //设置变量加
		flag=0;				  //关闭报警
		TR0=0;				  //关闭定时器
	}
	if(set==1)				  //设置报警值时
	{
		write_com(0x38);//屏幕初始化
		write_com(0x80+0x40+7);//位置
   		write_com(0x0f);//打开显示 无光标 光标闪烁
   		write_com(0x06);//当读或写一个字符是指针后一一位
		FENG=1;				//关闭蜂鸣器

	}
	else if(set>=2)		//设置完成时
	{
		set=0;			//变量清零
		write_com(0x38);//屏幕初始化
		write_com(0x0c);//打开显示 无光标 无光标闪烁
		FENG=1;			//关闭蜂鸣器
		flag=1;			//打开报警
		TR0=1;			//打开定时器
	}
	if(Key2==0&&set!=0)			//设置报警值时加键按下
	{
		while(Key2==0);			//按键松开
		FENG=0;					//打开蜂鸣器
		WARNING++;				//报警值加
		if(WARNING>=255)		//最大加到255
		WARNING=0;				//清零
		write_com(0x80+0x40+5);	   //选中液晶屏上的第二行第十一列
		write_data('0'+WARNING/100);   //开始显示报警值。例如报警值是123,123除以100的商是1,加上‘0’是为了得到液晶中对应1的显示码
		write_data('0'+WARNING%100/10);//123除以100的余数是23,23再除以10得到的商是2
		write_data('0'+WARNING%100%10);//23除以10的余数是3
		write_com(0x80+0x40+7);//位置
		FENG=1;						//关闭蜂鸣器
		write_eeprom();			   //保存数据
	}
	else if(Key2==0&&set==0)
	{
		AlcoholCalibration();  //酒精初始化校准
	}
	if(Key3==0&&set!=0)				//注释同加按键
	{
		while(Key3==0);
		FENG=0;
		WARNING--;
		if(WARNING<=0)
		WARNING=255;
		write_com(0x80+0x40+5);
		write_data('0'+WARNING/100);
		write_data('0'+WARNING/10%10);
		write_data('0'+WARNING%10);
		write_com(0x80+0x40+7);//位置
		FENG=1;
		write_eeprom();			   //保存数据
	}
}

void  time1_int(void) interrupt 1		  //定时器工作函数
{
	uchar count;						  //定义计时变量
	TL0=0xb0;
 	TH0=0x3c;							  //重新赋初值50ms
  	count++;							  //变量加一次就是50ms
	if(count==10)						  //加到10次就是500ms
	{
		if(flag==0)						  //flag=0时,也就是不开启报警
		{
			LED_G=0;					  //绿灯点亮
			LED_R=1;					  //红灯熄灭
			FENG=1;						  //关闭蜂鸣器
		}
		if(flag==1)						  //flag为1时,也就是打开报警
		{
			LED_G=1;					  //绿灯熄灭
			LED_R=0;					  //红灯点亮
			FENG=0;						  //打开蜂鸣器
		}
	}

   	if(count==20)						  //计数20次,就是1s
   	{									  //在1s时,红绿灯都是熄灭状态,蜂鸣器也是关闭状态,装可以达到闪烁的目的
		count=0;						  //变量清零
		if(flag==0)						  //不是报警状态时
		{
			LED_G=1;
			LED_R=1;
			FENG=1;
		}
		if(flag==1)						  //报警状态时
		{
			LED_G=1;
			LED_R=1;
			FENG=1;
		}
	}
} 

 

你可能感兴趣的:(51单片机实例,单片机,c语言)