本文介绍了 Nucleo-STM32C092 开发板通过硬件 IIC 与 AHT10 通信,采集环境温湿度并串口打印的流程。
## 项目方案
- 使用 STM32CubeMX 创建工程,配置 IIC 和 UART;
- STM32CubeIDE 代码编译和工程调试、固件上传;
- 实现基于 AHT10 传感器的环境温湿度的数据采集和串口打印。
## 工程创建
使用 STM32CubeMX 快速创建工程,开启 UART 并实现串口打印字符串。
- 打开 `STM32CubeMX` 软件,新建 ST 板卡工程,搜索 `NUCLEO-C092RC` 选中目标板卡,开始工程,选择默认外设配置(注意不使用 BSP 板级支持包);
- 时钟配置:采用默认设置,系统时钟频率 12MHz;
- `Pinout & Configuration` 标签下选择 `Connectivity` - 使能 `USART2` - 选择 `Asynchronous` 异步通信模式;
- `Pinout & Configuration` 标签下选择 `I2C1` - 使能 `I2C` - 注意到 GPIO 对应 PA9 (SCL) 和 PA10 (SDA);

- 配置完成后,进入 `Project Manager` 标签栏,进行项目命名、保存路径设置、编译器选择等操作;
- 点击 `Generate Code` 按钮,使用 **STM32CubeIDE** 或 Keil 打开目标工程;
- 编译工程,`0 error, 0 warning` .
## 硬件连接
| AHT10 引脚 | NUCLEO-C092RC 引脚 |
| :--------- | :----------------- |
| VCC | 3.3V |
| GND | GND |
| SDA | PA10 (I2C1_SDA) |
| SCL | PA9 (I2C1_SCL) |
实物连接

## 工程代码
### aht10.h
```c++
#ifndef __AHT10_H
#define __AHT10_H
#include "stm32c0xx_hal.h"
#define AHT10_I2C hi2c1
#define AHT10_ADDR 0x38 << 1 // 7位地址左移1位
// 函数声明
uint8_t AHT10_Init(void);
uint8_t AHT10_ReadData(float *temp, float *humi);
#endif
```
### aht10.c
```c++
#include "aht10.h"
#include "main.h"
#include <math.h>
extern I2C_HandleTypeDef AHT10_I2C;
// 初始化AHT10
uint8_t AHT10_Init(void) {
uint8_t cmd[3] = {0xE1, 0x08, 0x00}; // 初始化命令
if(HAL_I2C_Master_Transmit(&AHT10_I2C, AHT10_ADDR, cmd, 3, 100) != HAL_OK) {
return 1; // 通信失败
}
HAL_Delay(10); // 等待校准完成
return 0;
}
// 读取温湿度数据
uint8_t AHT10_ReadData(float *temp, float *humi) {
uint8_t txCmd[3] = {0xAC, 0x33, 0x00}; // 触发测量命令
uint8_t rxData[6] = {0};
// 1. 发送触发命令
if(HAL_I2C_Master_Transmit(&AHT10_I2C, AHT10_ADDR, txCmd, 3, 100) != HAL_OK) {
return 1;
}
// 2. 等待测量完成(约75ms)
HAL_Delay(80);
// 3. 读取6字节数据
if(HAL_I2C_Master_Receive(&AHT10_I2C, AHT10_ADDR, rxData, 6, 100) != HAL_OK) {
return 2;
}
// 4. 检查状态位(bit7=0表示忙)
if(rxData[0] & 0x80) {
return 3;
}
// 5. 转换湿度数据(单位:%RH)
uint32_t hum_raw = ((uint32_t)rxData[1] << 12) | ((uint32_t)rxData[2] << 4) | (rxData[3] >> 4);
*humi = (float)hum_raw * 100 / 1048576.0f; // 2^20=1048576
// 6. 转换温度数据(单位:℃)
uint32_t temp_raw = ((uint32_t)(rxData[3] & 0x0F) << 16) | ((uint32_t)rxData[4] << 8) | rxData[5];
*temp = (float)temp_raw * 200 / 1048576.0f - 50;
return 0;
}
```
### main.c
```c++
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
#include "aht10.h"
/* USER CODE END Includes */
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
// 初始化AHT11
if(AHT10_Init() != 0)
{
HAL_UART_Transmit(&huart2, (uint8_t*)"AHT11 Init Failed!\r\n", 19, 100);
while(1);
}
char msg[64];
float temp, humi;
/* USER CODE END 2 */
while (1)
{
/* USER CODE BEGIN 3 */
uint8_t ret = AHT10_ReadData(&temp, &humi);
if(ret == 0) {
sprintf(msg, "Temp: %.1f C, Humi: %.1f %%\r\n", temp, humi);
} else {
sprintf(msg, "Error: %d\r\n", ret);
}
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 100);
HAL_Delay(500); // 2秒更新一次
}
/* USER CODE END 3 */
}
```
## 效果

## 总结
本文介绍了 Nucleo-STM32C092 开发板通过硬件 IIC 与 AHT10 通信,采集环境温湿度并串口打印的流程,为相关产品的开发和设计提供了参考。
[/md]
aht10_c092rc_connect.jpg (116.39 KB )
cubemx_i2c1_uart_AHT10.jpg (142.12 KB )
aht10_print.gif (35.79 KB )
。
---------------------
作者:无垠的广袤
链接:https://bbs.21ic.com/icview-3454688-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。