这个单片机程序目前是显示PM2.5,温湿度,PM2.5传感器用的是GP2Y1014AU(模拟输出),温湿度用的是DHT11(数字输出),有个问题就是当K=Adc0832();这句放到中断里面,温湿度会变化,但是PM2.5就没有值,不会自己变化,得按一下复位键才显示值,当K=Adc0832();这句放到主函数里面,PM2.5就有值变化,但是温湿度的值没有了,按复位键也没有值。开始我怀疑中断函数影响了液晶屏的时序,但是后面直接给一个K值,PM2.5和温湿度都会变,我就找不到是哪里的问题了。有没有大神能帮忙看看是哪里的问题,程序和仿真图都在附件里。
PM2.5驱动条件:
关于驱动条件
根据LED驱动周期(脉冲周期:T (ms) ),LED驱动时间(脉冲:宽度Pw(ms) )输出电压会变动,规格书特性的规格值是脉冲周期T:10ms,脉冲宽度Pw:0.32ms,取样时间:0.28ms,根据此条件变动,规格书上规定的特性值(无尘时输出电压、检出感度)也随之变动。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- int temp;
- typedef unsigned int u16; //对数据类型进行声明定义
- typedef unsigned char u8;
- sbit LCDE=P1^2;
- sbit RS=P1^0;
- sbit RW=P1^1;
- sbit ADCS=P2^0; //ADC0832 chip seclect
- sbit ADDO=P3^7; //ADC0832 k in
- sbit ADDI=P3^7; //ADC0832 k in
- sbit ADCLK=P3^6; //ADC0832 clock signal
- sbit DHTIO=P2^1; //DHT11输出
- sbit LED=P2^7; //LED脉冲驱动
- unsigned char code digit[10]={"0123456789"};
- volatile uchar K=0;//AD转换数字量
- uint tempshi,tempge,humshi,humge;
- unsigned char U8FLAG=0,U8temp=0;
- unsigned char U8T_data_H=0,U8T_data_L=0,U8RH_data_H=0,U8RH_data_L=0,U8checkdata=0;
- unsigned char str[5];
- //humidity 湿度
- //temperature 温度
- //integer 整数
- //decimal 小数
- unsigned char humidity_interger=0,humidity_decimal;
- unsigned char temperature_integer=0,temperature_decimal;
- unsigned char check;
- void delay(unsigned int z) //延时长
- {
- unsigned char x,y;
- for(x=z;x>0;x--)
- {
- for(y=20;y>0;y--);
- }
- }
- void delay40us()
- {
- unsigned char a,b;
- for(b=3;b>0;b--)
- for(a=4;a>0;a--);
- }
-
- void delayms(uint del)
- {
- uint u,v;
- for(u=0;u<del;u++)
- for(v=0;v<=100;v++);
- }
- void delay20ms()
- {
- unsigned char a,b,c;
- for(c=1;c>0;c--)
- for(b=222;b>0;b--)
- for(a=40;a>0;a--);
- }
- unsigned char Adc0832() //AD转换,返回结果
- {
- uchar u=0;
-
- uchar dat=0;
- ADCLK=0;
- delayms(1);
- ADCS=0;//拉低CS端
- delayms(1);
- ADDI=1;
- delayms(1);
- ADCLK=1;//拉高CLK端
- delayms(1);
- ADCLK=0;//拉低CLK端,形成下降沿1
- delayms(1);
- ADCLK=1;//拉高CLK端
- ADDI=1;
- delayms(1);
- ADCLK=0;//拉低CLK端,形成下降沿2
- delayms(1);
- ADCLK=1;//拉高CLK端
- ADDI=1;
- delayms(1);
- ADCLK=0;//拉低CLK端,形成下降沿3
- delayms(1);
- ADDI=1;//控制命令结束
- delayms(1);
- dat=0;
- for(u=0;u<8;u++)
- {
- ADCLK=1;
- delayms(1);
- ADCLK=0;//形成一次时钟脉冲
- delayms(1);
- dat|=ADDO;//收数据
- if(u<7)
- dat<<=1;
- }
- for(u=0;u<8;u++)
- {
-
- ADCLK=1;
- delayms(1);
- ADCLK=0;//形成一次时钟脉冲
- delayms(1);
- }
- ADCS=1;//拉低CS端
- ADCLK=0;//拉低CLK端
- ADDO=1;//拉高数据端,回到初始状态
-
- return dat; //return ad k
-
- }
- void dht_start() //等待接受初始化
- {
- DHTIO=1; //初始高电平
- delay40us();
- DHTIO=0; //主机拉低电平
- delay20ms(); //保持电平时间大于18ms
- DHTIO=1; //主机拉高电平
- delay40us(); //延迟等待20-40us等待从机响应
- }
-
- unsigned char recieve_data() //数据接收
- {
- unsigned char i,flag,data_byte;
- for(i=0;i<8;i++)
- {
- flag=2;
- while((!DHTIO)&&flag++);//等待从机发出50us低电平结束
- delay40us(); //延时超过26us-28us不超过70us
- data_byte=data_byte<<1;
- if(DHTIO) //如果此时dhtio为1则表示此时从机输出数据为1否则说明此时从机输出数据为0
- {
- data_byte|=0x01;
- flag=2;
- while((DHTIO)&&flag++);//等待剩下的高电平结束
- }
- if(!flag)
- break;
- }
- return data_byte;
- }
- void dht_take_sample() //采样
- {
- unsigned char flag;
- dht_start();
- if(!DHTIO) //从机发出响应信号
- {
- flag=2;
- while((!DHTIO)&&flag++);//检测从机发出80us低电平是否结束
- flag=2;
- while((DHTIO)&&flag++); //检测从机发出80us高电平是否结束
- //开始采集数据
- humidity_interger=recieve_data(); //采集湿度整数部分
- humidity_decimal=recieve_data(); //采集湿度小数部分
- temperature_integer=recieve_data(); //采集温度整数部分
- temperature_decimal=recieve_data(); //采集温度小数部分
- check=recieve_data(); //采集校验位
-
- DHTIO=1; //采集数据后主机拉高电平
- }
- }
- void write_com(unsigned char com) //将模式设置指令或显示地址写入液晶模块
- {
- RS=0;
- RW=0;
- LCDE=0;
- P0=com;
- delay(5);
- LCDE=1;
- delay(5);
- LCDE=0;
- }
- void write_date(unsigned char date)//将数据(字符ASCII码)写入液晶模块
- {
- RS=1;
- RW=0;
- LCDE=0;
- P0=date;
- delay(5);
- LCDE=1;
- delay(5);
- LCDE=0;
- }
- void L1602_string(unsigned char hang,unsigned char lie,unsigned char p) //将数据写入液晶模块
- {
- unsigned char a;
- if(hang == 1) a = 0x80; //显示在第一行
- if(hang == 2) a = 0xc0; //显示在第一行
- a = a + lie -1;
- write_com(a);
- write_date(p);
- }
- void init() //1602初始化
- {
- write_com(0x38);
- write_com(0x0e);
- write_com(0x06);
- write_com(0x01);
- write_com(0x80);
- }
- void xianshi1() //pm2.5显示
- {
-
-
- L1602_string(1,1,'P');
- L1602_string(1,2,'M');
- L1602_string(1,3,'2');
- L1602_string(1,4,'.');
- L1602_string(1,5,'5');
- L1602_string(1,6,':');
- L1602_string(1,7,' ');
-
- L1602_string(1,8,K/100+0x30);
- L1602_string(1,9,(K-100*(K/100))/10+0x30);
- L1602_string(1,10,K%10+0x30);
- L1602_string(1,11,' ');
- L1602_string(1,12,'u');
- L1602_string(1,13,'g');
- L1602_string(1,14,'/');
- L1602_string(1,15,'m');
- L1602_string(1,16,'3');
- L1602_string(2,1,'T');
- L1602_string(2,2,'e');
- L1602_string(2,3,'m');
- L1602_string(2,4,'p');
- L1602_string(2,5,':');
- L1602_string(2,6,digit[tempshi]);
- L1602_string(2,7,digit[tempge]);
- L1602_string(2,8,'C');
- L1602_string(2,9,' ');
- L1602_string(2,10,'H');
- L1602_string(2,11,'u');
- L1602_string(2,12,'m');
- L1602_string(2,13,':');
- L1602_string(2,14,digit[humshi]);
- //L1602_string(2,14,(K-100*(K/100))/10+0x30);
- L1602_string(2,15,digit[humge]);
- //L1602_string(2,15,K%10+0x30);
- L1602_string(2,16,'%');
- }
- void readDH() //温湿度读取
- {
- dht_start();
- recieve_data();
- dht_take_sample();
- humshi=humidity_interger/10;
- humge=humidity_interger%10;
- tempshi=temperature_integer/10;
- tempge=temperature_integer%10;
- }
- void Timer0Init()
- {
- RW=0;
- LED=0;
- TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
- TH0=(65536-10000)%256;
- TL0=(65536-10000)/256; //定时10ms
- ET0=1;//打开定时器0中断允许
- EA=1;//打开总中断
- TR0=1;//打开定时器
-
- }
- void main() //主函数
- {
- int liu=0;
- LCDE=0;
- init();
- Timer0Init();
-
- while(1)
- {
-
- //liu++;
- // if(liu==245)
- //liu=0;
- // K=Adc0832();
- readDH();
- xianshi1();
- }
- }
- /**************************************
- /*****定时器0中断服务程序****/
- void Timer0() interrupt 1
- {
- static u16 j;
-
- // temp++;
- TH0 = (65536-10000)%256;
- TL0 = (65536-10000)/256;
-
- LED=1;
- //开启传感器的LED
- for (j=0;j<222;j++); //0.28ms //延时0.28ms
- K=Adc0832(); //开启ADC采集
- /* if(temp==20){
- K+=40;
- temp=0;
- } */
- //if(K>240)
- //K=0;
- //xianshi1();
- TR0 = 0; //先关闭定时器0
- EA = 0;
-
- LED=0;
- }
-
复制代码
所有资料51hei提供下载:
压缩文件.rar
(75.7 KB, 下载次数: 462)
|