AHT20温湿度传感器驱动源码分析 作者:马育民 • 2025-10-20 19:59 • 阅读:10011 摘自:https://blog.csdn.net/rsd102/article/details/110142409 # 程序源码 润和公司开源的鸿蒙OS AHT20 数字温湿度传感器驱动库: https://gitee.com/hihopeorg/harmonyos-aht20 # 模块的地址 I2C发送的首字节包括7位的I2C设备地址 `0x38` 和一个SDA方向位`X(读取是1,写入是0)` 手册中描述的模块地址定义如下: [](https://www.malaoshi.top/upload/0/0/1GW24patgr9o.png) 由上分析,我们得到读数据操作的首字节 `AHT20_READ_ADDR` 和写数据操作的首字节 `AHT20_WRITE_ADDR` 分别定义如下: ``` #define AHT20_DEVICE_ADDR 0x38 #define AHT20_READ_ADDR ((0x38<<1)|0x1) #define AHT20_WRITE_ADDR ((0x38<<1)|0x0) ``` # I2C写函数 [](https://www.malaoshi.top/upload/0/0/1GW24pdKZsEy.png) 上图中的 `AHT20_Write()` 函数中调用了 `I2cWrite()` 函数。 [](https://www.malaoshi.top/upload/0/0/1GW24pdmia67.png) ### 参数 I2cWrite()函数是系统中I2C进行写操作的函数,有以下3个参数: **参数1:**WifiIotI2cIdx id ,这个参数是使用的I2C的ID,这个参数可选下面枚举中的一个值: ``` typedef enum { /** I2C hardware index 0 */ WIFI_IOT_I2C_IDX_0, /** I2C hardware index 1 */ WIFI_IOT_I2C_IDX_1, } WifiIotI2cIdx; ``` 因为我们这里使用的是 `I2C0`,所以这个参数应该为:`WIFI_IOT_I2C_IDX_0` **参数2:**unsigned short deviceAddr,这个参数是I2C总线下面的设备地址,因为这是一个写操作,所以这个参数我们选用上面的宏定义:AHT20_WRITE_ADDR 。 **参数3:** `const WifiIotI2cData *i2cData` ,这个参数是我们要发送的数据,该变量的数据类型为一个结构体类型: HalWifiIotI2cData ,该结构体的定义如下。 ``` /** * @brief Defines I2C data transmission attributes. */ typedef struct { /** Pointer to the buffer storing data to send */ unsigned char *sendBuf; /** Length of data to send */ unsigned int sendLen; /** Pointer to the buffer for storing data to receive */ unsigned char *receiveBuf; /** Length of data received */ unsigned int receiveLen; } HalWifiIotI2cData; ``` # I2C读函数 [](https://www.malaoshi.top/upload/0/0/1GW24pgkZBnI.png) 上图中的AHT20_Read()函数中调用了I2cRead()函数。 [](https://www.malaoshi.top/upload/0/0/1GW24phL0MXN.png) I2cRead()函数是系统中I2C进行读操作的函数。 ### 参数 I2cRead()函数的参数与I2cWrite()函数的参数类似,只是参数3:`const WifiIotI2cData *i2cData` 用于接收我们读取到的数据。 # 常用命令 AHT20常用的命令有: - 初始化命令 (‘1011’1110’) ,即0xBE; - 测量温湿度命令(‘1010’1100’),即0xAC; - 软复位命令(‘1011’1010’),即0xBA。 [](https://www.malaoshi.top/upload/0/0/1GW24pjVGqtb.png) ### 状态位 通过发送0x71可以获取一个字节的状态字,状态字的描述如下表所示: [](https://www.malaoshi.top/upload/0/0/1GW24pkET9lf.png) # 传感器读取流程 上电后要等待40ms,读取温湿度值之前, 1. 首先要看状态字的校准使能位 `Bit[3]` 是否为 `1` (通过发送 `0x71` 可以获取一个字节的状态字) 2. 如果不为 `1`,要发送 `0xBE` 命令(初始化),此命令参数有两个字节, 第一个字节为 `0x08`,第二个字节为 `0x00`。 AHT20模块的状态判断通过下面 `AHT20_Calibrate()` 函数来判断,具体执行过程如下图所示: [](https://www.malaoshi.top/upload/0/0/1GW24q065fcm.png) 注:在第一步的校准状态检验只需要上电时检查,在正常过程无需操作。 # 软复位 上面代码中有一个这样的指令:AHT20_ResetCommand() 这个命令用于在无需关闭和再次打开电源的情况下,重新启动传感器系统。 在接收到这个命令之后,传感器系统开始重新初始化,并恢复默认设置状态,软复位所需时间不超过 20 毫秒。 [](https://www.malaoshi.top/upload/0/0/1GW24q1C4d4x.png) 灰色部分由 AHT20 控制 ``` #define AHT20_CMD_RESET 0xBA // 软复位命令 // 发送软复位命令 static uint32_t AHT20_ResetCommand(void) { uint8_t resetCmd[] = {AHT20_CMD_RESET}; return AHT20_Write(resetCmd, sizeof(resetCmd)); } ``` 直接发送 0xAC命令(触发测量),此命令参数有两个字节,第一个字节为 0x33,第二个字节为0x00。 触发测量命令发送的数据如下: [](https://www.malaoshi.top/upload/0/0/1GW24q2HCIG2.png) ``` #define AHT20_CMD_TRIGGER 0xAC // 触发测量命令 #define AHT20_CMD_TRIGGER_ARG0 0x33 #define AHT20_CMD_TRIGGER_ARG1 0x00 // 发送 触发测量 命令,开始测量 uint32_t AHT20_StartMeasure(void) { uint8_t triggerCmd[] = {AHT20_CMD_TRIGGER, AHT20_CMD_TRIGGER_ARG0, AHT20_CMD_TRIGGER_ARG1}; return AHT20_Write(triggerCmd, sizeof(triggerCmd)); } ``` 等待75ms待测量完成,忙状态Bit[7]为0,然后可以读取六个字节(发0X71即可以读取)。 [](https://www.malaoshi.top/upload/0/0/1GW24q3YODe9.png) 注:传感器在采集时需要时间,主机发出测量指令(0xAC)后,延时75毫秒以上再读取转换后的数据并判断返回的状态位是否正常。若状态比特位[Bit7]为0代表设备闲,可正常读取,为1时传感器为忙状态,主机需要等待数据处理完成。 [](https://www.malaoshi.top/upload/0/0/1GW24q4PDvXE.png) 计算温湿度值。 [](https://www.malaoshi.top/upload/0/0/1GW24q5CANgJ.png) # 相对湿度转换 上图中蓝色背景的六个字节数据中,红色方框框住的为湿度数据,组成一个20bit长度的一个整形数;紫色方框框住的20bit为温度数据。 湿度数据按下面代码实现拼接: ``` #define AHT20_RESOLUTION (1<<20) // 2^20 uint32_t humiRaw = buffer[1]; humiRaw = (humiRaw << 8) | buffer[2]; humiRaw = (humiRaw << 4) | ((buffer[3] & 0xF0) >> 4); ``` 通过手册我们得知相对湿度的计算公式如下: [](https://www.malaoshi.top/upload/0/0/1GW24q70EhfT.png) 用代码具体实现如下: ``` *temp = tempRaw / (float)AHT20_RESOLUTION * 200 - 50; ``` 原文出处:http://www.malaoshi.top/show_1GW24q8753qY.html