元器件清单 程序及注解 #include <AT89X52.h> #include <intrins.h> #define uint unsigned int #define uchar unsigned char //宏定义 sbit RS=P2^5;//液晶接口 sbit RW=P2^6; sbit EN=P2^7; sbit LED1 = P2^3;//指示灯接口 sbit LED2 = P2^0;//绿灯接口 sbit LED3 = P2^1;//黄灯接口 sbit LED4 = P2^2;//红灯接口 sbit LED = P1^1;//粉尘传感器控制接口 sbit ADCS = P1^4;//AD0832接口 sbit ADCLK = P1^0; sbit ADDI = P1^2; sbit ADDO = P1^ 2; sbit SET= P3^3;//按键接口 sbit ADD= P3^4; sbit DEC= P3^5; 46/55页 sbit BEEP=P3^6;//蜂鸣器接口 uchar set_st; uchar tab[4]; uint DUST_SET=35; //固体颗粒的阈值 bit shanshuo_st; //闪烁间隔标志 bit beep_st; //蜂鸣器间隔标志 uchar x=4; //计数器 //定义标识 uchar FlagStart = 0; float DUST_Value; uint DUST; uchar num=0; uchar mm; uchar abc; uchar ADC_Get[10]={0}; //定义AD采样数组 uchar str[5]={0}; /*****初始化定时器0*****/ void InitTimer(void) { TMOD = 0x01; TL0 = (65536-10000)/256; //定时10ms TH0 = (65536-10000)%256; TR0 = 1; ET0 = 1; EA = 1; } /*************************lcd1602程序**************************/ void delay1ms(uint ms)//延时1毫秒 { uint i,j; for(i=0;i<ms;i++) for(j=0;j<100;j++); } unsigned char rolmove(unsigned char m) { unsigned char a,b,c,d,e,f,g,h; a=(m&0x01)<<7; b=(m&0x02)<<5; c=(m&0x04)<<3; d=(m&0x08)<<1; e=(m&0x10)>>1; f=(m&0x20)>>3; g=(m&0x40)>>5; h=(m&0x80)>>7; m=a|b|c|d|e|f|g|h; return m; } void wr_com(uchar com)//写指令// { delay1ms(1); RS=0; RW=0; EN=0; P0=rolmove(com); delay1ms(1); EN=1; delay1ms(1); EN=0; } void wr_dat(uchar dat)//写数据// { delay1ms(1);; RS=1; RW=0; EN=0; P0=rolmove(dat); delay1ms(1); EN=1; delay1ms(1); EN=0; } /*****************************液晶初始化 *********************************************/ void lcd_init()//初始化设置// { delay1ms(15); wr_com(0x38);delay1ms(5); wr_com(0x08);delay1ms(5); wr_com(0x01);delay1ms(5); wr_com(0x06);delay1ms(5); wr_com(0x0c);delay1ms(5); wr_com(0x80); wr_dat('P');// wr_com(0x81); wr_dat('M');//: wr_com(0x82); wr_dat('2');// wr_com(0x83); wr_dat('.');//: 48/55页 wr_com(0x84); wr_dat('5');//: wr_com(0x85); wr_dat(':'); wr_com(0x8b); wr_dat('m'); wr_com(0x8c); wr_dat('g'); wr_com(0x8d); wr_dat('/'); wr_com(0x8e); wr_dat('m'); wr_com(0x8f); wr_dat('3'); wr_com(0xc0); wr_dat('A'); wr_com(0xc1); wr_dat('l'); wr_com(0xc2); wr_dat('a'); wr_com(0xc3); wr_dat('r'); wr_com(0xc4); wr_dat('m'); wr_com(0xc5); wr_dat(':'); wr_com(0xcb); wr_dat('m'); wr_com(0xcc); wr_dat('g'); wr_com(0xcd); wr_dat('/'); wr_com(0xce); wr_dat('m'); wr_com(0xcf); wr_dat('3'); } /*****************显示函数******************************/ void disp(unsigned int Data)//PM2.5值显示 { uint Temp; Temp=Data%10000; str[0]=Temp/1000+0x30; //千位 Temp%=1000; str[1]='.'; str[2]=Temp/100+0x30; //百位 Temp%=100; str[3]=Temp/10+0x30; //十位 str[4]=Temp%10+0x30; //个位 wr_com(0x87); wr_dat(str[0]); wr_com(0x88); wr_dat(str[1]); wr_com(0x89); wr_dat(str[2]); wr_com(0x8a); wr_dat(str[3]); } /************************报警值显示************************************/ void baojing() { wr_com(0xc7); wr_dat(tab[0]+0x30); wr_com(0xc8); wr_dat(tab[1]); wr_com(0xc9); wr_dat(tab[2]+0x30); wr_com(0xca); wr_dat(tab[3]+0x30); } /*****延时子程序*****/ void Delay(uint num) { while( --num ); } /**************************按键检测 *******************************************/ void checkkey() { if(SET==0) { Delay(2000); 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(2000); do{}while(DEC==0); if(DUST_SET>0)DUST_SET--; if(DUST_SET==0)DUST_SET=0; } if(ADD==0) { Delay(2000); do{}while(ADD==0); DUST_SET++; if(DUST_SET>80)DUST_SET=80; } } tab[0]=DUST_SET/100; tab[1]='.'; tab[2]=DUST_SET%100/10; tab[3]=DUST_SET%100%10; } /*****报警子程序*****/ void Alarm() { if(x>=10){beep_st=~beep_st;x=0;} if(DUST/10>DUST_SET&&beep_st==1)BEEP=1; else BEEP=0; if(DUST/10>0&&DUST/10<10){LED2=0;LED3=1;LED4=1;} if(DUST/10>=10&&DUST/10<30){LED2=1;LED3=0;LED4=1;} if(DUST/10>=30){LED2=1;LED3=1;LED4=0;} } /**************************AD0832转换程序 ***********************************************/ uchar ADC0832(bit mode,bit channel) //AD转换,返回结果 { uchar i,dat,ndat; ADCS = 0;//拉低CS端 _nop_(); _nop_(); ADDI = 1; //第1个下降沿为高电平 ADCLK = 1;//拉高CLK端 _nop_(); _nop_(); ADCLK = 0;//拉低CLK端,形成下降沿1 _nop_(); _nop_(); ADDI = mode; //低电平为差分模式,高电平为单通道模式。 ADCLK = 1;//拉高CLK端 _nop_(); _nop_(); ADCLK = 0;//拉低CLK端,形成下降沿2 _nop_(); _nop_(); ADDI = channel; //低电平为CH0,高电平为CH1 ADCLK = 1;//拉高CLK端 _nop_(); _nop_(); ADCLK = 0;//拉低CLK端,形成下降沿3 ADDI = 1;//控制命令结束(经试验必需) dat = 0; //下面开始读取转换后的数据,从最高位开始依次输出(D7~D0) for(i = 0;i < 8;i++) { dat <<= 1; ADCLK=1;//拉高时钟端 _nop_(); _nop_(); ADCLK=0;//拉低时钟端形成一次时钟脉冲 _nop_(); _nop_(); dat |= ADDO; } ndat = 0; //记录D0 if(ADDO == 1) ndat |= 0x80; //下面开始继续读取反序的数据(从D1到D7) for(i = 0;i < 7;i++) { ndat >>= 1; ADCLK = 1;//拉高时钟端 _nop_(); _nop_(); ADCLK=0;//拉低时钟端形成一次时钟脉冲 _nop_(); _nop_(); if(ADDO==1) ndat |= 0x80; } ADCS=1;//拉高CS端,结束转换 ADCLK=0;//拉低CLK端 ADDI=1;//拉高数据端,回到初始状态 if(dat==ndat) return(dat); else return 0; } /*****定时器0中断服务程序*****/ void timer0(void) interrupt 1 { uint j; TL0 = (65536-10000)/256; //定时10ms TH0 = (65536-10000)%256; LED=1; //开启传感器的LED x++; for (j=0;j<30;j++); //0.28ms //延时0.28ms abc=ADC0832(1,0); //开启ADC采集 FlagStart=1; TR0 = 0; //先关闭定时器0 EA = 0; LED1=~LED1;//工作指示灯 LED=0;//关闭传感器LED } //中值滤波 //算法:先进行排序,然后将数组的中间值作为当前值返回。 uchar Error_Correct(uchar *str,uchar num) { unsigned char i=0; unsigned char j=0; uchar Temp=0; //排序 for(i=0;i<num-1;i++) { for(j=i+1;j<num;j++) { if(str<str[j]) { Temp=str; str=str[j]; str[j]=Temp; } } } //去除误差,取中间值 return str[num/2]; } /*****主函数*****/ void main(void) { InitTimer(); //初始化定时器 LED=1; LED2=1; LED3=1; LED4=1; BEEP=0; lcd_init();//初始化显示 delay1ms(100); lcd_init();//初始化显示 delay1ms(100); while(1) { checkkey();//按键检测 if(set_st==0) { wr_com(0x0c); if(FlagStart==1) //1次数据采集完成 { num++; ADC_Get[num]=abc; if(num>9) { num=0; DUST=Error_Correct(ADC_Get,10); //求取10次AD采样的值 DUST_Value=(DUST/256.0)*5000; //转化成电压值MV DUST_Value=DUST_Value*0.17-0.1; //固体悬浮颗粒浓度计算 Y=0.17*X-0.1 X--采样电压V if(DUST_Value<0) DUST_Value=0; if(DUST_Value>760) DUST_Value=760; //限位 DUST=(uint)DUST_Value; } TL0 = (65536-10000)/256; TH0 = (65536-10000)%256; TR0 = 1; //开启定时器0 EA = 1; FlagStart=0; } Alarm(); //报警检测 } disp(DUST);//显示粉尘浓度值 baojing();//显示报警值 if(set_st==1)//报警值闪动 { wr_com(0xca); wr_com(0x0d); delay1ms(150); } } }/*****END*****/ 刚玩这个还不知道怎么发压缩文件以后会了再把仿真跟源码发上来 |