仿真图:
功能简介:
采用51单片机作为控制器,最小系统由晶振和复位电路组成
液晶显示采用LCD1602用于显示该项目的参数信息
具有多个功能按键,分别是设置、加、减等功能
采用ADC0809将传感器出来的模拟信号转换为数字信号再送入单片机处理
具有LED和蜂鸣器组成的声光报警电路
具有一路继电器驱动风扇,当监测到环境CO浓度高于设定阈值时该风扇启动
芯片/模块的特点:
ADC0809特点:
8位分辨率:ADC0809能够将模拟输入信号转换为8位的数字输出,提供256个离散的输出级别。这使得它适用于对较低分辨率要求的应用,可以进行精确的信号采集和转换。
并行输出:ADC0809的输出数据以并行方式进行传输,直接提供8位的数字输出。这种并行输出使得数据传输更加快速和高效。
内部参考电压:ADC0809集成了内部参考电压源,可以提供稳定且精确的参考电压。这样可以简化系统设计,并提高转换的准确性。
8个模拟输入通道:ADC0809具有8个模拟输入通道,可以分别转换8个不同的模拟输入信号。这使得它适用于多通道信号监测和数据采集的应用。
可编程时钟频率:ADC0809的转换速率可以通过外部时钟信号进行编程,可根据需要调整转换速度,以满足不同应用的需求。
外部控制引脚:ADC0809具有多个外部控制引脚,如转换启动引脚、自动触发引脚和片选引脚等,可以通过这些引脚对转换过程进行控制和选择。
多种封装形式:ADC0809可以提供不同的封装形式,如多引脚直插式封装(PDIP)和表面贴装技术(SMT)封装。这使得它适应不同应用的安装需求。
主程序:
//程序头函数
#include <reg52.h>
//显示函数
#include <display.h>
//宏定义
#define uint unsigned int
#define uchar unsigned char
#define Data_ADC0809 P1
//管脚声明
sbit LED_R= P2^2;//红灯
sbit LED_G= P2^0;//绿灯
sbit FENG = P2^1;//蜂鸣器
sbit san=P2^4; //风扇控制(选配)
//ADC0809
sbit ST=P3^7;
sbit EOC=P3^5;
sbit OE=P3^2;
//按键
sbit Key1=P3^3; //设置键
sbit Key2=P3^4; //加按键
sbit Key3=P3^6; //减按键
bit bdata flag; //报警标志位
uchar set; //设置状态
//函数声明
extern uchar ADC0809();
extern void Key();
//酒精含量变量
uchar temp=0;
uchar WARNING=25; //报警值
void init() //初始化函数
{
TMOD=0x01; //工作方式
TL0=0xb0;
TH0=0x3c; //赋初值(12MHz晶振的50ms)
EA=1; //打开中断总开关
ET0=1; //打开中断允许开关
TR0=1; //打开定时器开关
}
void main() //主函数
{
Init1602();//初始化显示
init(); //初始化定时器
while(1) //进入循环
{
temp=ADC0809(); //读取酒精浓度值
if(set==0) //只有在非设置状态时,
Display_1602(temp,WARNING); //才刷新显示实时浓度值
if(temp<WARNING&&set==0) //非设置时当浓度值小于报警值时
{
flag=0; //报警标志位置0,不报警
}
else if(temp>WARNING&&set==0) //非设置时当浓度值大于报警值时
{
flag=1; //报警标志位置1
}
Key(); //扫描按键
}
}
//ADC0809读取信息
uchar ADC0809()
{
uchar temp_=0x00;
//初始化高阻太
OE=0;
//转化初始化
ST=0;
//开始转换
ST=1;
ST=0;
//外部中断等待AD转换结束
while(EOC==0)
//读取转换的AD值
OE=1;
temp_=Data_ADC0809;//将0809的数值读入单片机
OE=0;
return temp_; //返回读到的数据
}
void Key() //按键函数
{
if(Key1==0) //设置键按下时
{
while(Key1==0); //检测按键是否释放
FENG=0; //蜂鸣器响
set++; //设置状态标志加
flag=0; //停止报警
san=1; //风扇停止转动(选配)
TR0=0; //定时器停止
write_com(0x80+0x40+13);//选中报警值的位置
write_com(0x0f);//打开显示 无光标 光标闪烁
}
if(set>=2) //再按一下设置键时,退出设置
{
set=0; //设置状态清零
write_com(0x38);//屏幕初始化
write_com(0x0c);//打开显示 无光标 无光标闪烁
FENG=1; //蜂鸣器停止响
flag=1; //报警标志位置1
TR0=1; //定时器开始计时
}
if(Key2==0&&set!=0) //当在设置状态时,按下加键时
{
while(Key2==0); //按键释放
FENG=0; //蜂鸣器鸣响
WARNING++; //报警阈值加
if(WARNING>=255)//阈值最大加到255
WARNING=0; //清零
write_com(0x80+0x40+11); //在阈值的位置写入设置的数据
write_data('0'+WARNING/100); //显示百位(将123除以100得到的商是1,就是百位数据)123为例子
write_data('0'+WARNING/10%10);//显示十位(将123除以10得到商是12,将12除以10的余数就是十位)
write_data('0'+WARNING%10); //显示个位(将123除以10的余数3就是个位数据)123为例子
write_com(0x80+0x40+13);//位置
FENG=1;//蜂鸣器停止
}
if(Key3==0&&set!=0) //减按键注释参考加按键部分
{
while(Key3==0);
FENG=0;
WARNING--;
if(WARNING<=0)
WARNING=255;
write_com(0x80+0x40+11);
write_data('0'+WARNING/100);
write_data('0'+WARNING/10%10);
write_data('0'+WARNING%10);
write_com(0x80+0x40+13);//位置
FENG=1;
}
}
void time1_int(void) interrupt 1 //定时器函数
{
uchar count;
TL0=0xb0;
TH0=0x3c; //重新赋初值
count++; //计时变量加
if(count==10)//定时器定时是50ms,此处计数10次,正好是500ms,用于报警时 灯亮和蜂鸣器响
{
if(flag==0) //报警标志为0时
{
LED_G=0; //绿灯亮
LED_R=1; //红灯灭
FENG=1; //蜂鸣器不响
san=1; //风扇不转(选配)
}
if(flag==1) //报警标志位为1时
{
LED_G=1; //绿灯灭
LED_R=0; //红灯亮
FENG=0; //蜂鸣器响
san=0; //风扇转动(选配)
}
}
if(count==20) //计数到20时,正好是1000ms,就是1s,这里就是让灯灭,蜂鸣器不响,从而做出闪烁的效果
{
count=0; //计到1s时,将count清零,准备重新计数
if(flag==0)
{
LED_G=1;
LED_R=1;
FENG=1;
san=1; //全部关闭
}
if(flag==1)
{
LED_G=1;
LED_R=1;
FENG=1;
san=0; //报警值,风扇是一直转动的(选配)
}
}
}
设计文件: