资讯详情

单片机烟雾传感器proteus仿真+程序+PCB原理图

利用ADC0832模拟烟雾传感器并报警

烟雾探测元件清单

942fea73984895256b9c24cabb6ff1f3.png

模拟原理图如下(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

共享资料的黑币奖励!

标签: k4光电传感器pcb传感器5302d传感器zh30104传感器qs30qae26传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台