news 2026/9/1 6:51:15

AHT20温湿度传感器使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AHT20温湿度传感器使用

工具准备:

STM32F407VGT-DISC开发板,AHT20温湿度传感器模块

CubeIDE,CubeMX,vscode

首先从GitHub上拉取驱动代码

libdriver/aht20: AHT20 full-featured driver library for general-purpose MCU and Linux.

然后在CubeMX中创建工程,首先将debug模式改为serial wire模式

打开外部时钟源

按如图所示设置时钟,模块挂载在APB1上

打开I2C1保持默认设置

打开串口2打印数据

勾选为每个外设分别生成.c.h文件

保存并生成代码

在usart.h中引入stdio.h,在usart.c文件中编写printf重定向函数,方便串口打印

/* USER CODE BEGIN 1 */ int __io_putchar(int ch) { HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } /* USER CODE END 1 */

用IDE打开项目在Core文件夹下新建CustomDrivers文件存放之前从GitHub上拉取的代码

右键工程点击properties

按下图步骤添加工作区,否则识别不到驱动文件

在i2c.h文件中引入driver_aht20.h文件,在i2c.c文件中编写获取温度,湿度的代码。

读取并编写获取温湿度代码的工作此处交由了vscode中配置的claude完成得到以下代码并添加到i2c.c中:

/* USER CODE BEGIN 1 */ /* ================== AHT20 接口层:把 LibDriver 驱动链接到 STM32 HAL I2C ================== */ /* IIC 传输超时时间,单位 ms */ #define AHT20_IIC_TIMEOUT 1000 /* AHT20 句柄(LibDriver 驱动要求,需链接 HAL 接口函数后使用) */ aht20_handle_t aht20_handle; /** * @brief IIC 初始化:I2C1 外设已由 MX_I2C1_Init() 完成初始化,此处直接返回成功 * @retval 0 成功 */ static uint8_t aht20_iic_init(void) { return 0; } /** * @brief IIC 反初始化:无特殊操作,返回成功 * @retval 0 成功 */ static uint8_t aht20_iic_deinit(void) { return 0; } /** * @brief 从 AHT20 读取 len 字节数据 * @note LibDriver 传入的 AHT20_ADDRESS(0x70) 已经是 STM32 HAL 所需的 * 移位后地址(7 位地址 0x38 << 1),因此直接透传,不要再移位。 * @param[in] addr 器件地址 * @param[out] buf 数据缓冲区 * @param[in] len 读取字节数 * @retval 0 成功,1 失败 */ static uint8_t aht20_iic_read_cmd(uint8_t addr, uint8_t *buf, uint16_t len) { if (HAL_I2C_Master_Receive(&hi2c1, addr, buf, len, AHT20_IIC_TIMEOUT) != HAL_OK) { return 1; } return 0; } /** * @brief 向 AHT20 写入 len 字节数据 * @param[in] addr 器件地址 * @param[in] buf 数据缓冲区 * @param[in] len 写入字节数 * @retval 0 成功,1 失败 */ static uint8_t aht20_iic_write_cmd(uint8_t addr, uint8_t *buf, uint16_t len) { if (HAL_I2C_Master_Transmit(&hi2c1, addr, buf, len, AHT20_IIC_TIMEOUT) != HAL_OK) { return 1; } return 0; } /** * @brief 毫秒延时 * @param[in] ms 延时毫秒数 */ static void aht20_delay_ms(uint32_t ms) { HAL_Delay(ms); } /** * @brief 调试打印:通过 printf 重定向输出到串口(usart.c 中已实现 __io_putchar) * @param[in] fmt 格式字符串 */ static void aht20_debug_print(const char *const fmt, ...) { va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); } /** * @brief AHT20 初始化:将接口函数链接到驱动句柄并初始化芯片 * @note 必须在 MX_I2C1_Init() 之后调用(在主循环前调用一次即可) * @retval 0 成功;非 0 失败(返回码含义见 driver_aht20.h 中 aht20_init 注释) */ uint8_t aht20_initialize(void) { DRIVER_AHT20_LINK_INIT(&aht20_handle, aht20_handle_t); DRIVER_AHT20_LINK_IIC_INIT(&aht20_handle, aht20_iic_init); DRIVER_AHT20_LINK_IIC_DEINIT(&aht20_handle, aht20_iic_deinit); DRIVER_AHT20_LINK_IIC_READ_CMD(&aht20_handle, aht20_iic_read_cmd); DRIVER_AHT20_LINK_IIC_WRITE_CMD(&aht20_handle, aht20_iic_write_cmd); DRIVER_AHT20_LINK_DELAY_MS(&aht20_handle, aht20_delay_ms); DRIVER_AHT20_LINK_DEBUG_PRINT(&aht20_handle, aht20_debug_print); return aht20_init(&aht20_handle); } /** * @brief 温度获取函数 * @retval 温度值(摄氏度),读取失败返回 -999.0f */ float aht20_get_temperature(void) { uint32_t temperature_raw; float temperature_s = -999.0f; if (aht20_read_temperature(&aht20_handle, &temperature_raw, &temperature_s) != 0) { return -999.0f; /* 读取失败 */ } return temperature_s; } /** * @brief 湿度获取函数 * @retval 相对湿度(%RH,保留小数),读取失败返回 -999.0f * @note 驱动返回的 humidity_s 是整数百分比,这里用原始值重新换算以保留小数位 */ float aht20_get_humidity(void) { uint32_t humidity_raw; uint8_t humidity_s; if (aht20_read_humidity(&aht20_handle, &humidity_raw, &humidity_s) != 0) { return -999.0f; /* 读取失败 */ } return (float)humidity_raw / 1048576.0f * 100.0f; } /* USER CODE END 1 */

在i2c.h中添加以下代码

/* USER CODE BEGIN Includes */ #include "driver_aht20.h" /* USER CODE END Includes */ extern I2C_HandleTypeDef hi2c1; /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ void MX_I2C1_Init(void); /* USER CODE BEGIN Prototypes */ uint8_t aht20_initialize(void); /* AHT20 初始化,须在 MX_I2C1_Init() 之后调用 */ float aht20_get_temperature(void); /* 获取温度,摄氏度,失败返回 -999.0f */ float aht20_get_humidity(void); /* 获取湿度,%RH,失败返回 -999.0f */ /* USER CODE END Prototypes */

接下来就可以正式在main文件中编写代码了

在main.c文件中写入以下代码:

/* USER CODE BEGIN 2 */ uint8_t ret = aht20_initialize(); if (ret != 0) { printf("AHT20 初始化失败,错误码:%d\r\n", ret); } else { printf("AHT20 初始化成功\r\n"); } float temperature = 0; float humidity = 0; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { temperature = aht20_get_temperature(); humidity = aht20_get_humidity(); if (temperature == -999.0f) { printf("温度读取失败\r\n"); } else { printf("温度:%.2f ℃\r\n", temperature); } if (humidity == -999.0f) { printf("湿度读取失败\r\n"); } else { printf("湿度:%.2f %%\r\n", humidity); } HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }

在CubeIDE中点击编译,无报错无警告,但是可以看到代码中有提示,浮点型变量不支持,这里需要修改设置

右键工程点击properties,按如图步骤勾选为printf支持浮点型变量,点击应用并关闭

硬件按MX配置接好线,串口如有问题可2查看我的另一篇文章嵌入式开发学习记录:USART串口通信,printf重定向到串口打印-CSDN博客

本实验中AHT20模块SDA接开发板PB7,SCL接PB6,VCC接3v3,GND接GND,具体情况看自己配置的MX,为开发板烧录代码,打开波特律动串口助手选择串口并连接,上电后发现温湿度都读取失败了,而且初始化也失败了

经过探测I2C总线上是否有设备应答发现并没有设备应答,据此可知是模块问题,目前模块是通过杜邦线和面包板连接到开发板上的,先检查能初步检查的事,如接线不良,换过面包板孔位,防止是面包板内部线路问题

在换过如下图线路接线后正常接收了一会信息,可是拔掉重新插回的时候又失效了,这说明元器件没问题,软件配置也没问题,问题一定是在接线或者面包板上,一般需要在SDA和SCL与接线柱间串个5k欧至10k欧的电阻方能得到较为稳定的数据,大概率是这一问题

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 6:47:56

A*与JPS算法对比:栅格地图路径规划的MATLAB实现与性能测试

简介&#xff1a;这是一份基于MATLAB的A 与JPS路径规划算法对比测试资源&#xff0c;覆盖1010至100100共6种不同分辨率的栅格地图&#xff0c;面向路径规划初学者、算法优化研究者以及机器人导航基础实验场景。压缩包共含38个文件&#xff0c;其中32个为.m脚本&#xff0c;并包…

作者头像 李华
网站建设 2026/9/1 6:47:05

Chrome v72绿色便携版:含完整运行组件,兼容老系统的实用方案

简介&#xff1a;谷歌浏览器72版绿色便携压缩包&#xff0c;集齐完整运行组件&#xff0c;面向需要兼容老旧网页技术、特定插件环境、自动化测试脚本或离线调试场景的用户。无需安装即可用&#xff0c;解压后双击主程序即可启动&#xff0c;保留该版本特有的页面渲染与脚本执行…

作者头像 李华
网站建设 2026/9/1 6:44:02

图像渲染GPU租用选型指南:RTX 4090与云平台对比

在图像渲染中&#xff0c;选择哪个GPU租用品牌最好如果你正在做3D渲染、视频剪辑或视觉特效工作&#xff0c;你大概率已经遇到了那个绕不开的痛点&#xff1a;本地显卡跑不动&#xff0c;买卡又太贵。一张RTX 4090显卡&#xff0c;目前市场价还在1.5万元以上&#xff0c;更不用…

作者头像 李华
网站建设 2026/9/1 6:43:19

复制延迟突然升高的排查路线——主备复制同步异常实践

文章目录每日一句正能量1. 背景与问题2. 环境与数据3. 复现过程故障排查流程图4. 方案实施主备切换演练1. 切换前检查2. 切换操作3. 切换后验证4. 回切流程演练指标对比5. 结果对比6. 风险与复盘7. 常见问题与排查误区误区一&#xff1a;WAL 积压导致磁盘满误区二&#xff1a;网…

作者头像 李华
网站建设 2026/9/1 6:42:45

中国省市县医院名单数据集 | 医院名单 医疗资源 空间分布 公共服务 区域发展 卫生健康数据 学术数据集8015期

中国省市县医院名单数据集 | 医院名单 医疗资源 空间分布 公共服务 区域发展 卫生健康数据 学术数据集8015期 数据集概述 本数据集系统整理了中国各省、市、县三级行政区的医院机构信息&#xff0c;涵盖等级、类型、规模及运营等核心指标。数据源于国家及省级卫健委官方注册信息…

作者头像 李华
网站建设 2026/9/1 6:41:40

DeepSeek渲染插件:让Agent输出秒变SVG图表与架构图

这次我们来看一个让 DeepSeek harness 的输出彻底告别纯文本的渲染插件。很多人在本地把 DeepSeek 接入 Codex 这类 Agent 工作流后发现&#xff0c;模型确实能思考、能改写代码&#xff0c;但最终呈现结果基本是一大段 Markdown 文本&#xff1b;想要一个组件架构图、一个数据…

作者头像 李华