代码实现1) 用 51 单片机做控制芯片,用 GY39 模块(ct、dr端)来实现光强和湿度的检测; 2) 光照值和湿度值通过计算后,要能够准确的显示在 LCD1602 上面; 3) 当光照值过低时自动的打开 LED 灯; 4) 当光照值过高时蜂鸣器报警 5) 适当创新
时间: 2024-05-07 19:23:12 浏览: 98
以下是基于51单片机和GY39模块的代码实现,实现了光强和湿度的检测并在LCD1602上显示,当光照值过低时自动打开LED灯,当光照值过高时蜂鸣器报警,同时添加了人体红外感应模块,当检测到人体时关闭LED灯和蜂鸣器。
```c
#include <reg52.h> // 51单片机头文件
#include <intrins.h> // 延时函数头文件
#define uint unsigned int
#define uchar unsigned char
sbit RS = P2^0; // LCD1602的RS引脚
sbit RW = P2^1; // LCD1602的RW引脚
sbit EN = P2^2; // LCD1602的EN引脚
sbit LED = P1^0; // LED灯引脚
sbit BEEP = P1^1; // 蜂鸣器引脚
sbit PIR = P3^2; // 人体红外感应模块引脚
uchar code table[] = "0123456789"; // 数字显示表
void delay(uint x) // 延时函数
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void write_com(uchar com) // 写入指令函数
{
RS = 0;
RW = 0;
P0 = com;
EN = 1;
delay(5);
EN = 0;
}
void write_data(uchar date) // 写入数据函数
{
RS = 1;
RW = 0;
P0 = date;
EN = 1;
delay(5);
EN = 0;
}
void init() // LCD1602初始化函数
{
write_com(0x38); // 初始化
write_com(0x0c); // 打开显示,关闭光标
write_com(0x06); // 光标右移,字符不移动
write_com(0x01); // 清屏
}
void display(uchar *p, uchar addr) // 显示数据函数
{
write_com(addr);
while(*p)
{
write_data(*p++);
}
}
uchar read_data() // 读取GY39模块数据函数
{
uchar date;
while(RI == 0);
date = SBUF;
RI = 0;
return date;
}
void main()
{
uchar hum_h, hum_l, temp_h, temp_l, light_h, light_l; // 存储读取的数值
float hum, temp, light; // 存储计算后的数值
uchar str[20]; // 存储要显示的字符串
init(); // LCD1602初始化
write_com(0x80); // 光标移到第一行第一列
display("Temp: ", 0x80); // 显示温度标题
display("Hum : ", 0xc0); // 显示湿度标题
while(1)
{
SCON = 0x50; // 串口工作方式1
TMOD = 0x20; // 定时器工作方式2
TH1 = 0xfd; // 波特率9600
TL1 = 0xfd;
TR1 = 1; // 启动定时器
ES = 1; // 打开串口中断
EA = 1; // 打开总中断
// 读取湿度值
SBUF = 0xff;
while(TI == 0);
TI = 0;
hum_h = read_data();
SBUF = 0xe1;
while(TI == 0);
TI = 0;
hum_l = read_data();
hum = (hum_h * 256 + hum_l) * 0.01;
sprintf(str, "%.2f%%", hum); // 将湿度值转换为字符串
display(str, 0xc5); // 在LCD1602上显示湿度值
// 读取温度值
SBUF = 0xff;
while(TI == 0);
TI = 0;
temp_h = read_data();
SBUF = 0xe3;
while(TI == 0);
TI = 0;
temp_l = read_data();
temp = (temp_h * 256 + temp_l) * 0.01;
sprintf(str, "%.2fC", temp); // 将温度值转换为字符串
display(str, 0x86); // 在LCD1602上显示温度值
// 读取光照值
SBUF = 0xff;
while(TI == 0);
TI = 0;
light_h = read_data();
SBUF = 0xe5;
while(TI == 0);
TI = 0;
light_l = read_data();
light = (light_h * 256 + light_l) * 0.25;
sprintf(str, "%.2fLx", light); // 将光照值转换为字符串
display(str, 0xcf); // 在LCD1602上显示光照值
// 根据光照值控制LED灯和蜂鸣器
if (light < 1000)
{
LED = 1;
}
else if (light > 2000)
{
BEEP = 1;
}
// 根据人体红外感应模块控制LED灯和蜂鸣器
if (PIR == 1)
{
LED = 0;
BEEP = 0;
}
}
}
void ser() interrupt 4 // 串口中断函数
{
RI = 0;
}
```
需要注意的是,以上代码只是一个简单的示例,实际使用时还需要根据具体情况进行修改和优化。
阅读全文