功能介绍
电路图
源代码
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>//printf串口输出头文件
#define uchar unsigned char
#define ushort unsigned int
#define uint unsigned long
#include "lcd1602.h"
#include "uart_trx.h"
#include "eeprom52.h"
#define RATIO 800 //系数,建议选择800-1000
sbit key1 = P1^0;//加键
sbit key2 = P1^1;//减键
sbit beep = P2^0;//蜂鸣器
sbit Fan = P1^3;//风扇
unsigned char pmBuf[7] = 0;//数据接收数组
uint PM25_Value = 0; //PM = ((pmBuf[1]<<8)+pmBuf[2])/1024*8*ratio
uint PM25_ValueMax = 200; //上限初始值
void EEPROM_WRITE()//EEPROM写入
{
SectorErase(0x2000);//擦除扇区
byte_write(0x2001, (PM25_ValueMax>>8)&0xFF);//存储高8位
byte_write(0x2002, (PM25_ValueMax>>0)&0xFF);//存储低8位
byte_write(0x2009, 111);//存储校验值
}
void EEPROM_READ()//EEPROM读出
{
if(byte_read(0x2009)!=111)//开机检测单片机是不是第一次使用,如果不是第一次使用,则先把数据存储一遍,再读取,数据就不会乱码
{
EEPROM_WRITE();//存储
delay_ms(100);
}
PM25_ValueMax = byte_read(0x2001)<<8 | byte_read(0x2002);//读取上限值
}
void Get_PM(void)//读取PM2.5值,具体的数据帧意思,请自行查阅芯片手册
{
char i = 0;
char j = 0;
char k = 0;
COM.RX_Cnt = 0;
if(COM.B_RX_OK == 1)//串口数据接收完成
{
for(i = 0; i<8; i++)
{
if((RX_Buffer[i] == 0xAA)&&(RX_Buffer[i+6]==0xFF))//判断接收的数据是否正确
{
goto find2;
}
}
goto end2;
find2:
for(j = 0; j<7; j++)
{
pmBuf[j] = RX_Buffer[i+j];//数据获取
}
PM25_Value = (unsigned int)((pmBuf[1]*256)+pmBuf[2])*5/2048.0*RATIO;//计算PM2.5值
COM.B_RX_OK = 0;
}
end2:
return;
}
void main(void)
{
unsigned int test;
EEPROM_READ();//开机读取存储值
LCD_init();//1602初始化
Uart_Init(2400);//串口初始化波特率2400
LCD_write_string(0,0,"Pm2.5: ug/m3 ");
LCD_write_string(0,1,"PmMax: ug/m3 ");
//显示上限值
LCD_write_char(7, 1, PM25_ValueMax % 1000 / 100 + 0x30);
LCD_write_char(8, 1, PM25_ValueMax % 100 / 10 + 0x30);
LCD_write_char(9, 1, PM25_ValueMax % 10 + 0x30);
while(1)
{
if (test ++ > 250)//大约250ms读取一次
{
test = 0 ;
Get_PM();//获取PM2.5
if(PM25_Value > 999)//限值,最大999
PM25_Value = 999;
//显示PM2.5
LCD_write_char(7, 0, PM25_Value % 1000 / 100 + 0x30);
LCD_write_char(8, 0, PM25_Value % 100 / 10 + 0x30);
LCD_write_char(9, 0, PM25_Value % 10 + 0x30);
if(PM25_Value >= PM25_ValueMax)//超过上限,蜂鸣器报警
{
beep = ~beep;
Fan = 0;
delay_ms(100);
}
else
{
beep = 1;
Fan = 1;
}
}
if(key1 == 0)//加键按下
{
delay_ms(10);//消抖
if(key1 == 0)
{
beep = 0;
delay_ms(100);
beep = 1;
while(key1 == 0);
if(PM25_ValueMax<999)PM25_ValueMax+=10;//上限最大到999,每次加10
//显示
LCD_write_char(7, 1, PM25_ValueMax % 1000 / 100 + 0x30);
LCD_write_char(8, 1, PM25_ValueMax % 100 / 10 + 0x30);
LCD_write_char(9, 1, PM25_ValueMax % 10 + 0x30);
EEPROM_WRITE();//保存
}
}
if(key2 == 0)//减键按下
{
delay_ms(10);
if(key2 == 0)
{
beep = 0;
delay_ms(100);
beep = 1;
while(key2 == 0);
if(PM25_ValueMax>=10)PM25_ValueMax-=10;//上限最小到0,每减10
//显示
LCD_write_char(7, 1, PM25_ValueMax % 1000 / 100 + 0x30);
LCD_write_char(8, 1, PM25_ValueMax % 100 / 10 + 0x30);
LCD_write_char(9, 1, PM25_ValueMax % 10 + 0x30);
EEPROM_WRITE();//保存
}
}
delay_ms(1);
}
}
系统框图
参考文献