51单片机at89c52,温湿度传感器测温,并在OLED中显示,保留小数点后三位,请给我代码
时间: 2023-12-08 21:04:08 浏览: 53
好的,根据您的需求,我为您提供以下代码。请注意,本代码基于Keil C51开发平台和STC89C52单片机,且需要外接温湿度传感器和OLED屏幕。
```c
#include <reg52.h>
sbit DHT11=P2^0; // 温湿度传感器数据信号接口
sbit SCL=P2^1; // OLED SCL时钟线接口
sbit SDA=P2^2; // OLED SDA数据线接口
void Delay10us() // 延时函数,用于IIC通讯
{
unsigned char i;
for (i=0;i<11;i++);
}
void IICStart() // IIC起始信号
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();
SDA=0;
Delay10us();
SCL=0;
Delay10us();
}
void IICStop() // IIC停止信号
{
SDA=0;
Delay10us();
SCL=1;
Delay10us();
SDA=1;
Delay10us();
}
void IICSendByte(unsigned char dat) // IIC发送字节
{
unsigned char i;
for (i=0;i<8;i++)
{
SDA=dat&0x80;
Delay10us();
SCL=1;
Delay10us();
SCL=0;
Delay10us();
dat<<=1;
}
}
unsigned char IICRecvByte() // IIC接收字节
{
unsigned char dat=0,i;
SDA=1;
Delay10us();
for (i=0;i<8;i++)
{
SCL=1;
Delay10us();
dat<<=1;
dat|=SDA;
SCL=0;
Delay10us();
}
return dat;
}
bit DHT11Check() // DHT11数据读取前的校验
{
unsigned char i;
for (i=0;i<100;i++);
DHT11=0;
Delay10us();
DHT11=1;
Delay10us();
if (DHT11==1) // DHT11响应
{
while (DHT11==1); // DHT11主机延时
return 1;
}
else return 0;
}
unsigned char DHT11RecvByte() // DHT11接收字节
{
unsigned char i,dat=0;
for (i=0;i<8;i++)
{
while (DHT11==0); // DHT11开始一个位的数据传输
Delay10us();
Delay10us();
Delay10us();
dat<<=1;
if (DHT11==1) dat|=1;
while (DHT11==1); // DHT11等待下一个位的数据传输
}
return dat;
}
void OLEDInit() // OLED屏幕初始化函数
{
IICStart();
IICSendByte(0x78);
IICSendByte(0x00);
IICSendByte(0xAE); // 关闭OLED显示
IICSendByte(0xD5);
IICSendByte(0x80);
IICSendByte(0xA8);
IICSendByte(0x3F);
IICSendByte(0xD3);
IICSendByte(0x00);
IICSendByte(0x40);
IICSendByte(0x8D);
IICSendByte(0x14);
IICSendByte(0x20);
IICSendByte(0x00);
IICSendByte(0xA1);
IICSendByte(0xC0);
IICSendByte(0xDA);
IICSendByte(0x12);
IICSendByte(0x81);
IICSendByte(0xCF);
IICSendByte(0xD9);
IICSendByte(0xF1);
IICSendByte(0xDB);
IICSendByte(0x30);
IICSendByte(0xA4);
IICSendByte(0xA6);
IICSendByte(0xAF); // 打开OLED显示
IICStop();
}
void DispChar(unsigned char x,unsigned char y,unsigned char num) // 显示一个字符
{
IICStart();
IICSendByte(0x78);
IICSendByte(0x00);
IICSendByte(0x21);
IICSendByte(x);
IICSendByte(x+7);
IICSendByte(0x22);
IICSendByte(y);
IICSendByte(y+15);
IICSendByte(0xb0+num-32);
IICStop();
}
void DispString(unsigned char x,unsigned char y,unsigned char *s) // 显示一个字符串
{
while (*s!=0)
{
DispChar(x,y,*s);
x+=8;
s++;
}
}
void main() // 主函数
{
unsigned char temp1=0,temp2=0,hum1=0,hum2=0;
float temp=0,hum=0;
OLEDInit(); // OLED屏幕初始化
while (1)
{
if (!DHT11Check()) continue; // DHT11读取前的校验失败,重新读取
hum1=DHT11RecvByte();
hum2=DHT11RecvByte();
temp1=DHT11RecvByte();
temp2=DHT11RecvByte();
if ((hum1+hum2+temp1+temp2)!=DHT11RecvByte()) continue; // DHT11数据校验失败,重新读取
hum=hum1+hum2/10.0;
temp=temp1+temp2/10.0;
DispString(0,0,"Temperature:");
DispString(0,2,"Humidity :");
DispString(96,0,"C");
DispString(96,2,"%");
DispString(72,0," "); // 清除之前的数据
DispString(72,2," ");
DispString(72,0,"%f",temp); // 在OLED屏幕上显示温度
DispString(72,2,"%f",hum); // 在OLED屏幕上显示湿度
}
}
```
在以上代码中,DHT11Check函数、DHT11RecvByte函数和IICStart函数、IICStop函数、IICSendByte函数和IICRecvByte函数分别表示了DHT11温湿度传感器数据读取前的校验和IIC通讯协议的相关函数。OLEDInit函数、DispChar函数和DispString函数则表示了OLED屏幕的初始化、在指定位置显示一个字符和在指定位置显示一个字符串的函数。在main函数中,我们首先读取DHT11传感器的数据,计算得到温度和湿度的值,然后在OLED屏幕上显示出来。其中,DispString函数使用了类似printf函数的方式来格式化输出字符串和浮点数。