From 7a3b64472d2fba0efbbddbd1b6e982880d027251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=B1=20=E6=B2=88?= <2401809606@qq.com> Date: Sun, 28 Dec 2025 15:24:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=A0=E6=84=9F=E5=99=A8=E9=A9=B1=E5=8A=A8(d?= =?UTF-8?q?s1307/ds3231)(ahtx0=5Fth)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cproject | 2106 ++++++++++---------- applications/drv/drv_aht20.c | 218 ++ {drivers => applications/drv}/drv_ds1307.c | 2 +- 3 files changed, 1272 insertions(+), 1054 deletions(-) create mode 100644 applications/drv/drv_aht20.c rename {drivers => applications/drv}/drv_ds1307.c (99%) diff --git a/.cproject b/.cproject index 13472b1..162ccf9 100644 --- a/.cproject +++ b/.cproject @@ -1,1056 +1,1056 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/drv/drv_aht20.c b/applications/drv/drv_aht20.c new file mode 100644 index 0000000..d29848b --- /dev/null +++ b/applications/drv/drv_aht20.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2025, Your Name + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2025-12-27 Developer First version for AHT20 on RT-Thread + */ + +#include +#include +#include + +#define DBG_TAG "sensor.aht20" +#define DBG_LVL DBG_LOG +#include + +/* AHT20 I2C 地址 */ +#define AHT20_I2C_ADDR 0x38 +/* 使用的 I2C 总线设备名 */ +#define AHT20_I2C_BUS_NAME "i2c2" // 根据你的板子修改,如 "i2c2" + +static struct rt_i2c_bus_device *i2c_bus = RT_NULL; + +/** + * 向 AHT20 发送命令 + */ +static rt_err_t aht20_send_cmd(rt_uint8_t cmd, const rt_uint8_t *data, rt_size_t len) +{ + rt_uint8_t buf[3] = {cmd}; + if (len > 0) + { + rt_memcpy(&buf[1], data, len); + } + + struct rt_i2c_msg msgs[1] = { + { + .addr = AHT20_I2C_ADDR, + .flags = RT_I2C_WR, + .buf = buf, + .len = 1 + len, + } + }; + + if (rt_i2c_transfer(i2c_bus, msgs, 1) != 1) + { + LOG_E("I2C send command 0x%02X failed.", cmd); + return -RT_ERROR; + } + return RT_EOK; +} + +/** + * 从 AHT20 读取数据 + */ +static rt_err_t aht20_read_data(rt_uint8_t *buf, rt_size_t len) +{ + struct rt_i2c_msg msgs[1] = { + { + .addr = AHT20_I2C_ADDR, + .flags = RT_I2C_RD, + .buf = buf, + .len = len, + } + }; + + if (rt_i2c_transfer(i2c_bus, msgs, 1) != 1) + { + LOG_E("I2C read data failed."); + return -RT_ERROR; + } + return RT_EOK; +} + +/** + * 初始化 AHT20 + */ +static rt_err_t aht20_init_sensor(void) +{ + rt_uint8_t status = 0; + rt_uint8_t cmd_data[2] = {0x08, 0x00}; + + /* 发送初始化命令 */ + if (aht20_send_cmd(0xBE, cmd_data, 2) != RT_EOK) + { + LOG_E("Failed to send init command."); + return -RT_ERROR; + } + + rt_thread_mdelay(20); // 等待初始化完成 + + /* 读取状态字节(可选) */ + if (aht20_read_data(&status, 1) == RT_EOK) + { + LOG_D("AHT20 status: 0x%02X", status); + } + + return RT_EOK; +} + +/** + * 触发一次温湿度测量 + */ +static rt_err_t aht20_trigger_measure(void) +{ + rt_uint8_t cmd[2] = {0x33, 0x00}; + return aht20_send_cmd(0xAC, cmd, 2); +} + +/** + * 读取原始温湿度数据(6 字节) + */ +static rt_err_t aht20_fetch_raw(rt_uint8_t raw[6]) +{ + return aht20_read_data(raw, 6); +} + +/** + * 解析原始数据为温度(0.1°C)和湿度(0.1%RH) + */ +static void aht20_parse_data(const rt_uint8_t raw[6], rt_int32_t *temp, rt_int32_t *humi) +{ + rt_uint32_t humi_raw = ((rt_uint32_t)raw[1] << 12) | ((rt_uint32_t)raw[2] << 4) | (raw[3] >> 4); + rt_uint32_t temp_raw = ((rt_uint32_t)raw[3] & 0x0F) << 16 | ((rt_uint32_t)raw[4] << 8) | raw[5]; + + *humi = (rt_int32_t)((humi_raw * 1000) / (1 << 20)); // 转换为 0.1%RH + *temp = (rt_int32_t)((temp_raw * 2000) / (1 << 20) - 500); // 转换为 0.1°C(公式:T = (raw / 2^20) * 200 - 50) +} + +/** + * AHT20 读取线程 + */ +static void aht20_thread_entry(void *parameter) +{ + rt_uint8_t raw_data[6]; + rt_int32_t temperature, humidity; + + while (1) + { + if (aht20_trigger_measure() != RT_EOK) + { + LOG_E("Trigger measurement failed."); + rt_thread_mdelay(2000); + continue; + } + + rt_thread_mdelay(80); // AHT20 典型转换时间 75ms + + if (aht20_fetch_raw(raw_data) != RT_EOK) + { + LOG_E("Fetch raw data failed."); + rt_thread_mdelay(2000); + continue; + } + + /* 检查忙标志(bit7 of raw_data[0] 应为 0)*/ + if (raw_data[0] & 0x80) + { + LOG_W("AHT20 is busy, retrying..."); + rt_thread_mdelay(100); + continue; + } + + aht20_parse_data(raw_data, &temperature, &humidity); + + LOG_I("Temp: %d.%dC, Humidity: %d.%dRH", + temperature / 10, temperature % 10, + humidity / 10, humidity % 10); + + rt_thread_mdelay(5000); // 每 2 秒读取一次 + } +} + +/** + * AHT20 驱动初始化函数 + */ +static int rt_hw_aht20_init(void) +{ + i2c_bus = rt_i2c_bus_device_find(AHT20_I2C_BUS_NAME); + if (i2c_bus == RT_NULL) + { + LOG_E("Failed to find I2C bus: %s", AHT20_I2C_BUS_NAME); + return -RT_ENOSYS; + } + + LOG_I("Found I2C bus: %s", AHT20_I2C_BUS_NAME); + + if (aht20_init_sensor() != RT_EOK) + { + LOG_E("AHT20 sensor initialization failed!"); + return -RT_ERROR; + } + + LOG_I("AHT20 initialized successfully."); + + /* 创建读取线程 */ + rt_thread_t tid = rt_thread_create("ahtX0", + aht20_thread_entry, + RT_NULL, + 512, + RT_THREAD_PRIORITY_MAX - 2, + 10); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } + else + { + LOG_E("Failed to create AHT20 thread."); + return -RT_ERROR; + } + + return RT_EOK; +} + +/* 自动初始化 */ +INIT_APP_EXPORT(rt_hw_aht20_init); diff --git a/drivers/drv_ds1307.c b/applications/drv/drv_ds1307.c similarity index 99% rename from drivers/drv_ds1307.c rename to applications/drv/drv_ds1307.c index 5296cad..b1d7055 100644 --- a/drivers/drv_ds1307.c +++ b/applications/drv/drv_ds1307.c @@ -210,7 +210,7 @@ static int rt_hw_ds1307_rtc_init(void) ds1307_read_time(); - ds1307.thd_soft_update_sec = rt_thread_create("ds1307",auto_update_current_datatime,RT_NULL,512, 20, 5); + ds1307.thd_soft_update_sec = rt_thread_create("ds1307",auto_update_current_datatime,RT_NULL,256, 20, 5); if (ds1307.thd_soft_update_sec) { rt_thread_startup(ds1307.thd_soft_update_sec);