| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- /******************************************************************************
- 版权所有:
- 文件名称: aht20.c
- 文件版本: 01.01
- 创建作者: Ewen
- 创建日期: 2025-11-10
- 功能说明: aht20驱动程序。
- 其它说明:
- 修改记录:
- /*------------------------------ 头文件 ---------------------------------------
- */
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <linux/i2c.h>
- #include <linux/i2c-dev.h>
- #include <errno.h>
- #include "head.h"
- #ifdef TMP_CHIP_AHT20
- /*------------------------------ 宏定义 ---------------------------------------
- */
- #define I2C_DEV "/dev/i2c-5"
- // 以下定义见AHT20 datasheet
- // AHT20 设备地址
- #define AHT20_I2C_ADDR 0x38
- // AHT20 命令字
- #define AHT20_CMD_INIT 0xBE
- #define AHT20_CMD_MEAS 0xAC
- #define AHT20_CMD_RESET 0xBA
- /*------------------------------ 全局变量 -------------------------------------
- */
- struct aht20 aht20;
- int g_aht20_fd;
- /*------------------------------ 函数声明 -------------------------------------
- */
- // AHT20 初始化
- static int _aht20_init(int fd) {
- uint8_t init_cmd[3] = {AHT20_CMD_INIT, 0x08, 0x00};
-
- if (write(fd, init_cmd, sizeof(init_cmd)) != sizeof(init_cmd))
- {
- printf("Failed to send init command: %s\n", strerror(errno));
- return -1;
- }
-
- return 0;
- }
- // AHT20 软复位
- static int _aht20_soft_reset(int fd) {
- uint8_t reset_cmd = AHT20_CMD_RESET;
-
- if (write(fd, &reset_cmd, sizeof(reset_cmd)) != sizeof(reset_cmd))
- {
- printf("Failed to send reset command: %s\n", strerror(errno));
- return -1;
- }
-
- return 0;
- }
- // 读取温湿度数据
- static int _aht20_read_data(int fd, float* temperature, float* humidity)
- {
- uint8_t cmd[3] = {AHT20_CMD_MEAS, 0x33, 0x00};
- uint8_t data[6] = {0};
- uint32_t temp_raw = 0, humi_raw = 0;
-
- // 发送测量命令
- if (write(fd, cmd, sizeof(cmd)) != sizeof(cmd)) {
- printf("Failed to send measure command: %s\n", strerror(errno));
- return -1;
- }
-
- // 等待测量完成(最多100ms)
- int timeout = 0;
- while (timeout < 100) {
- msleep(1);
- if (read(fd, data, 1) == 1) {
- if (!(data[0] & 0x80)) { // 检查忙标志位
- break;
- }
- }
- timeout++;
- }
-
- if (timeout >= 100) {
- printf("AHT20 measurement timeout\r\n");
- return -1;
- }
-
- // 读取测量数据
- if (read(fd, data, sizeof(data)) != sizeof(data)) {
- printf("Failed to read measurement data: %s\r\n", strerror(errno));
- return -1;
- }
-
- // 检查数据状态位
- if ((data[0] & 0x68) != 0x08) {
- printf("AHT20 data not ready or invalid\r\n");
- return -1;
- }
-
- // 解析湿度数据(20位)
- humi_raw = ((uint32_t)data[1] << 12) |
- ((uint32_t)data[2] << 4) |
- ((uint32_t)data[3] >> 4);
-
- // 解析温度数据(20位)
- temp_raw = (((uint32_t)data[3] & 0x0F) << 16) |
- ((uint32_t)data[4] << 8) |
- data[5];
-
- // 转换为实际值
- *humidity = (float)humi_raw * 100.0 / (1 << 20);
- *temperature = (float)temp_raw * 200.0 / (1 << 20) - 50.0;
-
- return 0;
- }
- int aht20_init(void)
- {
- memset(&aht20, 0, sizeof(aht20));
- // 打开I2C设备
- g_aht20_fd = open(I2C_DEV, O_RDWR);
- if (g_aht20_fd < 0) {
- printf("Failed to open I2C device %s: %s\n", I2C_DEV, strerror(errno));
- return -1;
- }
- // 设置从设备地址
- if (ioctl(g_aht20_fd, I2C_SLAVE, AHT20_I2C_ADDR) < 0) {
- printf("Failed to set I2C slave address: %s\n", strerror(errno));
- close(g_aht20_fd);
- return -1;
- }
- _aht20_soft_reset(g_aht20_fd);
- msleep(100);
- if(_aht20_init(g_aht20_fd) == 0)
- {
- printf("aht20 init success!\r\n");
- }
- else
- {
- printf("aht20 init failed!\r\n");
- close(g_aht20_fd);
- g_aht20_fd = -1;
- return -1;
- }
- aht20.us0 = bsp_ustimer_get_origin();
- return 0;
- }
- int aht20_exit(void)
- {
- if(g_aht20_fd >= 0)
- {
- close(g_aht20_fd);
- g_aht20_fd = -1;
- }
- return 0;
- }
- void aht20_task(void)
- {
- if(bsp_ustimer_get_duration(aht20.us0) < USTIMER_SEC*5 || g_aht20_fd < 0)
- {
- return;
- }
- aht20.us0 = bsp_ustimer_get_origin();
- _aht20_read_data(g_aht20_fd, &aht20.temp, &aht20.humi);
- // printf("aht20.temp=%.3f ℃, aht20.humi=%.3f %%RH\r\n", aht20.temp, aht20.humi);
- }
- float aht20_get_temp(void)
- {
- if(g_aht20_fd < 0)
- {
- // 校准系数判断 温度低于-85℃时为异常状态,温度补偿系数默认改为1.0,
- // 因此此处在初始化失败时返回-100.0℃
- return -100.0;
- }
- return aht20.temp;
- }
- float aht20_get_humi(void)
- {
- return aht20.humi;
- }
- #endif /* TMP_CHIP_AHT20 */
|