STM32H5使用I2C协议读取温湿度数据涉及硬件连接、驱动配置和软件编程等步骤。下面是一个大致的指南:
1. 硬件连接
将温湿度传感器AHT10通过I2C接口连接到STM32H5开发板上。确保传感器的电源和地线正确连接,并且SDA(数据线)和SCL(时钟线)分别连接到开发板的对应I2C引脚上。
PC2--SCL
PC3--SDA
2. 驱动配置
STM32H5支持硬件I2C和软件模拟I2C两种方式。
硬件I2C:利用STM32H5的硬件I2C外设进行通信,通常效率更高,稳定性更好。你需要在STM32CubeMX或其他配置工具中启用I2C外设,并配置相关参数,如通信速率、中断等。
软件模拟I2C:通过软件控制GPIO引脚来模拟I2C的时序和通信过程。这种方式更为灵活,但可能效率稍低。你需要编写代码来控制GPIO引脚的输入输出状态,以模拟I2C总线的数据传输和设备地址选择。
3. 软件编程
在STM32H5上,你可以使用HAL库或LL库来编写I2C通信的代码。
以下是一个简化的软件流程:
a. 初始化I2C
需要初始化I2C外设或GPIO引脚,设置其工作模式和参数。
b. 寻址传感器
通过I2C发送设备的地址和命令,以激活温湿度传感器。这通常涉及发送启动信号、发送设备地址和读写位等信息。
c. 读取数据
根据传感器的数据手册,发送正确的命令以从传感器读取温湿度数据。这通常涉及等待传感器的响应、读取数据字节等步骤。
d. 解析数据
从传感器读取的原始数据通常需要按照特定的格式进行解析,以转换为实际的温度和湿度值。
e. 数据处理与输出
处理解析后的数据,并通过串口或其他接口将其发送到OLED进行显示。
注意事项
确保在编程时遵循传感器的数据手册和时序要求。
调试过程中,可以使用串口打印或其他调试工具来检查通信过程和读取的数据。
对于复杂的系统,可能需要考虑线程同步、错误处理和数据校验等问题。
正常连接状态:
IIC时序:
IIC协议的时序简单来说就是两条线之间的关系,分别为时钟线SCL和数据线SDA。IIC协议的时序图的状态主要分为空闲态、起始位、停止位以及数据的读/写状态。
在空闲状态下,数据线SDA和时钟线SCL都保持高电平。起始位是由时钟线SCL为高电平,数据线SDA出现一个下降沿来产生的,表示一次通信的开始。停止位则是时钟线SCL为高电平,数据线SDA出现一个上升沿,表示通信的结束。
数据传输过程中,SDA上的数据变化只能在SCL低电平期间发生,以确保数据的稳定性。当主设备要发送数据时,首先发送一个起始信号,然后发送从设备的地址,由7位地址和一个读/写位组成。接着进行数据传输,每个字节的传输都以一个起始位、8位数据和一个应答位结束。从设备在接收到数据后会发送应答信号,表示已经成功接收。
代码:
// 初始化AHT10的I2C时钟线SCL的GPIO端口时钟 AHT10_I2C_SCL_GPIO_RCC; // 初始化AHT10的I2C数据线SDA的GPIO端口时钟 AHT10_I2C_SDA_GPIO_RCC; // 这里的注释“??GPIO??”可能是乱码或占位符,应该替换为描述性的文字,如“初始化SDA的GPIO时钟” // 定义GPIO初始化结构体 GPIO_InitTypeDef GPIO_InitStruct; // 设置GPIO初始化结构体的成员 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 设置为推挽输出模式 // GPIO_InitStruct.Pull = GPIO_NOPULL; // 这行代码被注释掉了,如果取消注释,将设置GPIO无上拉或下拉 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 设置GPIO速度为高频 // 设置SCL的引脚号 GPIO_InitStruct.Pin = AHT10_I2C_SCL_PIN; // 使用HAL库函数初始化SCL的GPIO HAL_GPIO_Init(AHT10_I2C_SCL_GPIO_PORT, &GPIO_InitStruct); // 设置SDA的引脚号并重新初始化SDA的GPIO GPIO_InitStruct.Pin = AHT10_I2C_SDA_PIN; HAL_GPIO_Init(AHT10_I2C_SDA_GPIO_PORT, &GPIO_InitStruct); // 将SDA和SCL设置为高电平,这通常是I2C空闲状态 AHT10_SDA_H; AHT10_SCL_H; // 初始化AHT10的I2C通信函数(这部分可能是用户自定义的) AHT10_IIC_Init(); // 发送I2C起始信号 AHT10_IIC_Start(); // 发送AHT10的器件地址(注意这里的地址可能需要查阅AHT10的数据手册) AHT10_IIC_Send_Byte(AHT10_ADDRESS); // 发送读取命令(0xe1可能是读取命令,具体需要参考AHT10的数据手册) AHT10_IIC_Send_Byte(0xe1); // 发送读取数据的寄存器地址(0x08和0x00可能是温度和湿度的寄存器地址) AHT10_IIC_Send_Byte(0x08); AHT10_IIC_Send_Byte(0x00); // 发送I2C停止信号 AHT10_IIC_Stop(); // 等待40毫秒,这通常是为了让传感器有足够的时间响应请求(数据手册可能推荐等待20ms,但这里选择了40ms) AHT10_Delay_ms(40); // 读取AHT10的数据(这部分可能是用户自定义的) ret=AHT10ReadData(&temperature,&humidity); // 检查读取数据是否成功 if(ret==0) { // 如果失败,显示“recv temp fail!”字符串 GUI_ShowString(0,0,(unsigned char*)"recv temp fail!",8,1); } else { // 如果成功,将读取到的温度和湿度数据转换为浮点数 float temp=temperature*0.1; float hum=humidity*0.1; // 创建并填充包含温度和湿度的字符串 char print_temp[64]; char print_hum[64]; sprintf(print_temp,"temp:%2.1f du",temp); sprintf(print_hum,"hum:%2.1f%%",hum); // 显示温度和湿度的字符串 GUI_ShowString(0,0,(unsigned char*)print_temp,16,1); GUI_ShowString(0,2,(unsigned char*)print_hum,16,1); // 显示一个固定字符串 GUI_ShowString(0,4,(unsigned char*)"hello word!",16,1); }
正常环境温度:
手摸到模块温度: