功能介绍
电路图
pcb
源代码
#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);
}
}
元器件清单
基于51/stm32单片机的智能药盒 物联网定时吃药 药品分类的设计与实现 | ||
名称 | 型号 | 数量 |
单片机 | stc89c52 | 1 |
ic座 | dip40 | 1 |
万能板 | 9*15cm | 1 |
晶振 | 11.0592m | 1 |
电解电容 | 10uf | 1 |
电解电容 | 1000uf | 1 |
瓷片电容 | 22pf | 2 |
电阻 | 10k | 3 |
电阻 | 1k | 4 |
电阻 | 2k | 1 |
led红 | 5mm | 1 |
led绿 | 5mm | 1 |
蜂鸣器 | 有源 | 1 |
三极管 | s9012 | 1 |
按键 | 5 | |
显示屏 | lcd1602 | 1 |
排针 | 16p | 1 |
排母 | 16p | 1 |
人体红外模块 | hc-sr501 | 1 |
排母 | 3p | 1 |
温度传感器 | ds18b20 | 1 |
烟雾传感器 | mq-2 | 1 |
模数转换器 | adc0832 | 1 |
ic座 | 8p | 1 |
gsm模块 | sim800c | 1 |
电源座 | 5mm | 1 |
电源线 | 5v2a | 1 |
自锁开关 | 1 | |
继电器 | 1 | |
小水泵 | 1 | |
导线 | 若干 | |
焊锡丝 | 若干 |
参考文献
实物可做,资料齐全,其他功能也可做~
发表评论