一、系统方案
本设计采用STC15单片机作为主控制器,PM2.5传感器、按键设置,液晶1602显示,蜂鸣器报警。
二、硬件设计
原理图如下:
三、单片机软件设计
1、首先是系统初始化:
void lcd_init()//液晶初始化设置
{
delay1ms(15);
wr_com(0x38);//设定LCD为161显示,57点阵,8位数据接口
delay1ms(5);
wr_com(0x01);//清显示屏
delay1ms(5);
wr_com(0x06);//地址计数器增,显示屏不移动
delay1ms(5);
wr_com(0x0c);//开显示,不显示光标
delay1ms(5);
}
2、液晶显示程序
void wr_com(uchar com)//写指令
{
delay1ms(5);
RS=0;
EN=0;
P0=com;
delay1ms(5);
EN=1;
delay1ms(5);
EN=0;
}
void wr_dat(uchar dat)//写数据
{
delay1ms(5);
RS=1;
EN=0;
P0=dat;
delay1ms(5);
EN=1;
delay1ms(5);
EN=0;
}
3、按键检测程序
void checkkey()//按键检测
{
if(key1==0)
{
Delay(10000);
do{}while(key1==0);
mode++;
if(mode>1)mode=0;
}
if(key20)
{
Delay(10000);
do{}while(key20);
count++;
if(count>4)count=0;
}
if(SET==0)
{
Delay(10000);
do{}while(SET==0);
set_st++;
if(set_st>1)set_st=0;
}
if(set_st==0)
{
}
else if(set_st==1)
{
if(DEC==0)
{
Delay(10000);
do{}while(DEC==0);
if(DUST_SET>0)DUST_SET--;
if(DUST_SET==0)DUST_SET=0;
}
if(ADD==0)
{
Delay(10000);
do{}while(ADD==0);
DUST_SET++;
if(DUST_SET>800)DUST_SET=800;
byte_write(0x2200,DUST_SET/256);
byte_write(0x2201,DUST_SET%256);
}
if(ADD1==0)
{
Delay(10000);
do{}while(ADD1==0);
DUST_SET=DUST_SET+10;
if(DUST_SET>800)DUST_SET=800;
}
if(DEC1==0)
{
Delay(10000);
do{}while(DEC1==0);
if(DUST_SET>10||DUST_SET==10)DUST_SET=DUST_SET-10;
if(DUST_SET<0||DUST_SET==0)DUST_SET=0;
byte_write(0x2200,DUST_SET/256);
byte_write(0x2201,DUST_SET%256);
}
}
tab[0]=DUST_SET/1000;
tab[1]='.';
tab[2]=DUST_SET%1000/100;
tab[3]=DUST_SET%100/10;
tab[4]=DUST_SET%10;
}
4、核心算法程序
void INTadc()//ADC 初始化
{
P1ASF=0x10; //设置P1.4做ADC输入通道 0001 0000b
ADC_CONTR=0xC4; //电源打开,速度360T,选择通道4 1100 0100b
CLK_DIV &=0xDF; //(ADRJ)=0,高八位在ADC_RES,低两位在ADC_RESL 1101 1111b
delay1ms(1);
ADC_CONTR=0xCC; //启动AD转换 1010 1100b
EADC=1;
EA=1;
}
void dataprocess()
{
DUST=ADC_RES;
DUST=DUST<<2;//左移两位
DUST=DUST+ADC_RESL;
DUST_Value=(DUST/1024.0)*5;//转化成电压值
DUST_Value=(DUST_Value*0.17-0.1)*1000;//固体悬浮颗粒浓度计
if(DUST_Value<0) DUST_Value=0;
if(DUST_Value>760) DUST_Value=760; //限位
DUST=(uint)DUST_Value;
// wei[0]=ad_data/1000;
// wei[1]=ad_data%1000/100;
// wei[2]=ad_data%100/10;
// wei[3]=ad_data%10;
ADC_RES=0x00;
ADC_RESL=0; //清零
ADC_CONTR=0xCC;
}
void adc_isr() interrupt 5
{
ADC_CONTR=0xC4; //启动AD转换
dataprocess();
// ADC_RES=0x00;
// ADC_RESL=0; //清零
}
void timer0(void) interrupt 1//定时器0中断服务程序
{
uint j;
TL0 = (65536-10000)/256; //定时10ms
TH0 = (65536-10000)%256;
LED=1; //开启传感器的LED
x++;
for (j=0;j<30;j++); //延时0.28ms
ADC_CONTR=0xCC; //启动AD转换
// abc=ad_data;
FlagStart=1;
TR0 = 0; //先关闭定时器0
EA = 0;
LED=0;//关闭传感器LED
}
//中值滤波
//算法:先进行排序,然后将数组的中间值作为当前值返回。
uchar Error_Correct(uchar *str,uchar num)
{
unsigned char i=0;
unsigned char j=0;
unsigned char Temp=0;
//排序
for(i=0;i<num-1;i++)
{
for(j=i+1;j<num;j++)
{
if(str[i]<str[j])
{
Temp=str[i];
str[i]=str[j];
str[j]=Temp;
}
}
}
四、proteus仿真设计
Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。