I2C读取AHT10温湿度数据需要结合传感器的数据手册来编写代码。
#include "aht10.h"
#include "delay.h"
#include "iic.h"
u8 AHT10_Write_Data(u8 cmd, u8 *data, u8 len)
{
IIC_Start();
IIC_Send_Byte((AHT10_IIC_ADDR << 1) | 0);
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(cmd);
IIC_Wait_Ack();
for(u8 i = 0; i < len; i++)
{
IIC_Send_Byte(data[i]);
IIC_Wait_Ack();
}
IIC_Stop();
return 0;
}
u8 AHT10_ReadOneByte(void)
{
u8 res = 0;
IIC_Start();
IIC_Send_Byte((AHT10_IIC_ADDR << 1) | 0X01);
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
res = IIC_Read_Byte(0);
IIC_Stop();
return res;
}
u8 AHT10_Read_Data(u8 *data, u8 len)
{
IIC_Start();
IIC_Send_Byte((AHT10_IIC_ADDR << 1) | 0x01);
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
for(u8 i = 0; i < len; i++)
{
if(i == (len - 1))
data[i] = IIC_Read_Byte(0);
else
data[i] = IIC_Read_Byte(1);
}
IIC_Stop();
return 0;
}
float AHT10_Read_Temperature(void)
{
u8 res = 0;
u8 cmd[2] = {0, 0};
u8 temp[6];
float cur_temp;
res = AHT10_Write_Data(AHT10_GET_DATA, cmd, 2);
if(res) return 1;
res = AHT10_Read_Data(temp, 6);
if(res) return 1;
cur_temp = ((temp[3] & 0xf) << 16 | temp[4] << 8 | temp[5]) * 200.0 / (1 << 20) - 50;
return cur_temp;
}
float AHT10_Read_Humidity(void)
{
u8 res = 0;
u8 cmd[2] = {0, 0};
u8 humi[6];
float cur_humi;
res = AHT10_Write_Data(AHT10_GET_DATA, cmd, 2);
if(res) return 1;
res = AHT10_Read_Data(humi, 6);
if(res) return 1;
cur_humi = ((humi[1]) << 12 | humi[2] << 4 | (humi[3] & 0xF0)) * 100.0 / (1 << 20);
return cur_humi;
}
u8 AHT10_Init(void)
{
u8 res;
u8 temp[2] = {0, 0};
IIC_Init();
res = AHT10_Write_Data(AHT10_NORMAL_CMD, temp, 2);
if(res != 0) return 1;
delay_ms(300);
temp[0] = 0x08;
temp[1] = 0x00;
res = AHT10_Write_Data(AHT10_CALIBRATION_CMD, temp, 2);
if(res != 0) return 1;
delay_ms(300);
return 0;
}
#define AHT10_IIC_ADDR 0x38
#define AHT10_CALIBRATION_CMD 0xE1
#define AHT10_NORMAL_CMD 0xA8
#define AHT10_GET_DATA 0xAC
u8 AHT10_Init(void);
float AHT10_Read_Temperature(void);
float AHT10_Read_Humidity(void);
关于采集的数据处理方法作如下说明: 手册中说在发送0xAC命令后再次发送从机地址及读命令,从机开始发送状态位、20位、20位。在I2C按位接收的过程中使用6个字节来存放接收到的温湿度数据,最先接收到的8位是状态位Status我们不做处理。因此湿度数据就是humi[1]、humi[2]和humi[3]的高4位;温度数据就是temp[3]的低四位、temp[4]、temp[5]。根据手册给出的温湿度转化公式,可以计算出实际的温度、湿度。
cur_humi = ((humi[1]) << 12 | humi[2] << 4 | (humi[3] & 0xF0)) * 100.0 / (1 << 20);
cur_temp = ((temp[3] & 0xf) << 16 | temp[4] << 8 | temp[5]) * 200.0 / (1 << 20) - 50;
|