利用ADC0832模拟烟雾传感器并报警
烟雾探测元件清单
模拟原理图如下(proteus本帖附件可下载仿真工程文件)
Altium Designer画原理图和PCB图如下:(51hei工程文件可在附件中下载)
单片机源程序如下:
#include //头文件包含单片机寄存器
#include //包含_nop_()函数定义的头文件
#define uchar unsigned char
#define uint unsigned int
uchar a,q,t,t1;
long int s1,d0,b,c,d,s,e1,biao,biao1,biao2,a1;
uchar code qw[]={1,1,1};
uchar qs[5]={0
uchar key_buffer[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};//2013-01-03
sbit clk=P1^1; //时钟
sbit cs=P1^0; //片选端
sbit d1=P1^2; ///开始信号输入和端口选择
sbit rs=P2^5; //将rS位定义为P2.5引脚
sbit e=P2^7; //定义e位P2.7引脚
sbit rw=P2^6; //将rw位定义为P2.6引脚
sbit k1=P1^4;
sbit k2=P1^5;
sbit k3=P1^6;
sbit k4=P1^7;
sbit D1=P2^0; ///正常指示灯(绿灯)
sbit D2=P2^1; ///警示灯(红灯)
sbit beep=P2^二、//蜂鸣器
uchar code tad[]="value:00000ppm";
uchar code tad1[]="Alarm:09000ppm";
/*****************************************************
函数功能:延迟几毫秒
入口参数:x
***************************************************/
void delay(uchar x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=90;b>0;b--);
}
uchar du()//读AD转换数据
{
uchar i,k,j;
cs=0; ///片选有效
for(j=0;j<3;j ) ///通道选择
{
clk=1;
d1=qw[j];
for(q=0;q<2;q ) _nop_();
clk=0;
for(q=0;q<2;q ) _nop_();
}
for(i=0;i<8;i )
{
clk=1;
for(q=0;q<2;q )_nop_();
clk=0;
for(q=0;q<2;q ) _nop_();
k=(k<<1)|d1;
}
cs=1;
for(q=0;q<28;q ) _nop_();//延迟
return k;//返回AD0832转换值
}
/*****************************************************
液晶显示器LED1602
******************************************************/
void write_date(uchar date)
{
rs=1;
P0=date;
delay(5);
e=1;
delay(5);
e=0;
}
void write_com(uchar com)
{
rs=0;
P0=com;
delay(5);
e=1;
delay(5);
e=0;
}
void init()
{
uchar num;
e=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<14;num )
{
write_date(tad[num]);
delay(2);
}
write_com(0x80 0x40);
for(num=0;num<14;num )
{
write_date(tad1[num]);
delay(2);
}
}
void write_sfm(uint date)/
{
uint wan,pian,bai,shi,ge;
wan=date/10000;
pian=date000/1000;
bai=date00000/100;
shi=date000000/10;
ge=date000000;
write_com(0x80 6);
write_date(0x30 wan);
write_date(0x30 pian);
write_date(0x30 bai);
write_date(0x30 shi);
write_date(0x30 ge);
}
void zh()//AD数据处理
{
a=du();
b=(a/51);//整数
s=(aQ);
s1=(s*10)//整形两个字节
c=(s1/51)
d=(s1Q);
d0=(d*10);//整形
e1=(d0/51)
b=b*100;
c=c*10;
a1=(b c e1);//a必须定义为长整形
delay(10);
if(a1>140)
{
<>a1=a1-140;if(a1>=0)
{
a1=(a1*1000)/36;
write_sfm(a1);
}
}
else
write_sfm(0);
}
/*****************************************************
函数功能:报警子程序
*****************************************************/
void zx()//控制
{
long int sa;
sa=((qs[3]*1000)+(qs[2]*100)+(qs[1]*10)+qs[0]); //报警设定值
if(a1>sa) //烟雾检测值大于设定值
{
D2=0; //报警红灯亮
D1=1; //正常指示绿灯灭
biao2=1; //蜂鸣器报警标志置1
}
else
{
D1=0; //正常指示绿灯亮
D2=1; //报警红灯灭
biao2=0; //蜂鸣器报警标志清0
beep=1; //蜂鸣器不响
}
}
/*****************************************************
函数功能:按键识别
******************************************************/
void key_scan()//按键识别
{
uchar i;
static uchar key_value,key_state=0;
P1=0xf0;//设置P1口高4位为输入口
if((P1&0xf0)!=0xf0)//有键按下
{
delay(2); //延时消抖
key_state =P1&0xf0;
if(key_state!=0xf0) //再判有键按下
{
switch(key_state)
{
case 0xe0: //S1按下
key_value=1;
break;
case 0xd0://S2按下
key_value=2;
break;
case 0xb0: //S3按下
key_value=3;
break;
case 0x70: //S4按下
key_value=4;
break;
}
for(i=0;i<7;i++) //按键队列FIFO处理
{
key_buffer[ i]=key_buffer[i+1];
}
key_buffer[7]=key_value; //最新按键值存入缓冲队列
}
while((P1&0xf0)!=0xf0); //等待按键释放
}
}
/*****************************************************
函数功能:按键处理
******************************************************/
void key_do() // 按键处理
{
uchar d,i;
while((key_buffer[0]!=0xff)||(key_buffer[1]!=0xff)||(key_buffer[2]!=0xff)||(key_buffer[3]!=0xff)||(key_buffer[4]!=0xff)||
(key_buffer[5]!=0xff)||(key_buffer[6]!=0xff)||(key_buffer[7]!=0xff))//有键按下
{
switch(key_buffer[0])
{
case 1: //S1按下
biao++;
t1=1;
TR1=0;
if(biao==5)
{
TR1=1;
biao=0;
write_com(0x0c);//关闭光标闪烁
}
biao1=0;
break;
case 2://S2按下
if(biao==1)
{
if(biao1==0)
{
write_com(0x80+0x40+10);//定位光标闪烁的位置
write_com(0x0f); //打开光标闪烁
}
d=qs[0];
d++;
if(d==10) d=0;
write_com(0x80+0x40+10);
write_date(0x30+d);//送显示
write_com(0x80+0x40+10);//重新定位光标闪烁的位置
qs[0]=d;
//biao1=1;
}
if(biao==2)
{
if(biao1==0)
write_com(0x80+0x40+9);//定位光标闪烁的位置
d=qs[1];
d++;
if(d==10) d=0;
write_com(0x80+0x40+9);
write_date(0x30+d);//送显示
write_com(0x80+0x40+9);//重新定位光标闪烁的位置
qs[1]=d;
//biao1=1;
}
if(biao==3)
{
if(biao1==0)
write_com(0x80+0x40+8);//定位光标闪烁的位置
d=qs[2];
d++;
if(d==10) d=0;
write_com(0x80+0x40+8);
write_date(0x30+d);//送显示
write_com(0x80+0x40+8);//重新定位光标闪烁的位置
qs[2]=d;
}
if(biao==4)
{
if(biao1==0)
write_com(0x80+0x40+7);//定位光标闪烁的位置
d=qs[3];
d++;
if(d==10) d=0;
write_com(0x80+0x40+7);
write_date(0x30+d);//送显示
write_com(0x80+0x40+7);//重新定位光标闪烁的位置
qs[3]=d;
}
biao1=1;
break;
case 3: //S3按下
if(biao==1)
{
if(biao1==0)
{
write_com(0x80+0x40+10);//定位光标闪烁的位置
write_com(0x0f); //打开光标闪烁
}
d=qs[0];
d--;
if(d==-1) d=9;
write_com(0x80+0x40+10);
write_date(0x30+d);//送显示
write_com(0x80+0x40+10);//重新定位光标闪烁的位置
qs[0]=d;
// biao1=1;
}
if(biao==2)
{
if(biao1==0)
write_com(0x80+0x40+9);//定位光标闪烁的位置
d=qs[1];
d--;
if(d==-1) d=9;
write_com(0x80+0x40+9);
write_date(0x30+d);//送显示
write_com(0x80+0x40+9);//重新定位光标闪烁的位置
qs[1]=d;
}
if(biao==3)
{
if(biao1==0)
write_com(0x80+0x40+8);//定位光标闪烁的位置
d=qs[2];
d--;
if(d==-1) d=9;
write_com(0x80+0x40+8);
write_date(0x30+d);//送显示
write_com(0x80+0x40+8);//重新定位光标闪烁的位置
qs[2]=d;
}
if(biao==4)
{
if(biao1==0)
write_com(0x80+0x40+7);//定位光标闪烁的位置
d=qs[3];
d--;
if(d==-1) d=9;
write_com(0x80+0x40+7);
write_date(0x30+d);//送显示
write_com(0x80+0x40+7);//重新定位光标闪烁的位置
qs[3]=d;
}
biao1=1;
break;
case 4: //S4按下
TR1=1;
biao=0;
write_com(0x0c);//关闭光标闪烁
break;
default: break;
}
for(i=0;i<7;i++) //按键队列FIFO处理
{
key_buffer[ i]=key_buffer[i+1];
}
key_buffer[7]=0xff; //缓冲队列单元恢复无键按下标志
}
}
void init1()
{
biao=0;
biao1=0;biao2=0;beep=1;
cs=1;
clk=0;
d1=0;
rw=0;
EA=1;
ET1=1;
TMOD=0x10;
TH1=(65536-50000)/256;
TL1=(65535-50000)%256;
TR1=1;
t1=0;
D1=0;
init();
}
/*****************************************************
函数功能:主函数
***************************************************/
main()
{
init1();
while(1)
{
if(biao==0) //若打开报警功能
zx(); //调报警函数
key_scan();
key_do();//调按键处理函数,进行报警值设定
if(t1==0) //定时时间到0.2s
{
zh(); //调数据转换, 启动AD转换
t1=1; //关闭数据转换和AD转换
}
}
}
void as() interrupt 3 //定时器T1中断函数 ,定时启动数据转换和AD转换,并根据情况进行蜂鸣器报警
{
TH1=(65536-50000)/256;//重赋初值
TL1=(65535-50000)%256;
t++; //时间计数加1
if(t==4) //50ms*4=0.2s,0.2s时间到
{
t=0; //时间计数清0
t1=!t1; //启动数据转换和AD转换
if(biao2==1)
beep=!beep; //蜂鸣器报警
}
}
程序问题还很多,大家能帮我修改一下吗?仿真图屏幕没有反应:
烟雾探测报警器.7z
(269.35 KB, 下载次数: 79)
2020-5-21 20:20 上传
点击文件名下载附件
可以参考这个可用:http://www.51hei.com/bbs/dpj-80294-1.html
评分
黑币 +50
收起
理由
+ 50
共享资料的黑币奖励!