十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AHT20温湿度传感器使用

AHT20温湿度传感器使用 工具准备STM32F407VGT-DISC开发板AHT20温湿度传感器模块CubeIDECubeMXvscode首先从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接开发板PB7SCL接PB6VCC接3v3GND接GND具体情况看自己配置的MX为开发板烧录代码打开波特律动串口助手选择串口并连接上电后发现温湿度都读取失败了而且初始化也失败了经过探测I2C总线上是否有设备应答发现并没有设备应答据此可知是模块问题目前模块是通过杜邦线和面包板连接到开发板上的先检查能初步检查的事如接线不良换过面包板孔位防止是面包板内部线路问题在换过如下图线路接线后正常接收了一会信息可是拔掉重新插回的时候又失效了这说明元器件没问题软件配置也没问题问题一定是在接线或者面包板上一般需要在SDA和SCL与接线柱间串个5k欧至10k欧的电阻方能得到较为稳定的数据大概率是这一问题
返回列表