STM32 I2C通信协议与温湿度传感器模块

学习I2C总线通信协议,使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出


一、预备知识

(1) I2C通信协议

I2C通信协议是一种用于串行通信的协议,常被用于连接微控制器、传感器、外设等。它使用两根线(SDA和SCL)来进行双向通信。其中,SDA线用于数据传输,而SCL线用于时钟同步。在I2C通信中,所有设备都有一个固定的地址,用于唯一标识设备。主设备可以向从设备发送指令,也可以接收从设备的响应和数据。在传输数据时,每个数据字节都由一个起始位、8位数据位、1位确认位和1位停止位组成。通信过程中,串行数据传输的时钟频率可以在100KHz、400KHz甚至更高的速度下运行。

(2) I2C物理层

I2C通讯设备之间的常用连接方式:
在这里插入图片描述
物理层特点:
1.它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个I2C通讯总线中,可连接多个I2C通讯设备,支持多个通讯主机及多个通讯从机。

2.一个I2C总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线 (SCL)。数据线即用来表示数据,时钟线用于数据收发同步。

3.每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。

4.总线通过上拉电阻接到电源。当I2C设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。

5.多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。

(3)I2C时序

整体时序:
在这里插入图片描述
上图状态描述:
1.空闲状态:无数据传输,I2C设备不工作;
2.起始状态:等待数据输入,由SDA信号拉低控制;
3.读写状态:数据传输;
4.停止状态:从传输跳转到空闲,由SDA信号拉低控制。

传输状态时序:
在这里插入图片描述
串行时钟线SCL高电平期间,采集SDA数据信号,SDA信号保持稳定。在SCL低电平期间,SDA改变数据,以此串行传输数据。

当一个完整字节的指令或数据传输完成,从机设备正确接收到指令或数据后,会通过拉低SDA为低电平,向主机设备发送单比特的应答信号,表示数据或指令写入成功。若从机正确应答,可以结束或开始下一字节数据或指令的传输,否则表明数据或指令写入失败,主机就可以决定是否放弃写入或者重新发起写入

(4)硬件I2C和软件I2C

硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的;
软件I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信;

二、AHT20温湿度传感器

上面介绍了I2C通信协议,下面介绍温湿度传感器模块,以及怎样实现用I2C通信协议与温湿度传感器模块通信,读取温湿度信息。

通过阅读产品手册,我们可以知道温湿度传感器模块的接口定义:
在这里插入图片描述
发送命令和指令集:

在启动传输后,随后传输的I2C首字节包括7位2 的I C设备地址 0x38和一个SDA方向位 x(读R:‘1’,写W:‘0’)。在第8个SCL时钟下降沿之后,通过拉低 SDA引脚 (ACK位),指示传感器数据接收正常。 在发送测量命令0xAC之后,MCU必须等到测量完成。

在这里插入图片描述
读取流程:

1.上电后要等待40ms,读取温湿度值之前, 首先要看状态字的校准使能位Bit[3]是否为 1(通过发送0x71可以获取一个字节的状态字),如果不为1,要发送0xBE命令(初始化),此命令参数有两个字节, 第一个字节为0x08,第二字节为0x00,然后等待10ms。
2.直接发送 0xAC命令(触发测量),此命令参数有两个字节,第一个字节为 0x33,第二个字节为0x00。
3.等待80ms待测量完成,如果读取状态字Bit[7]为0,表示测量完成,然后可以连续读取六个字节;否则继续等待。
4.当接收完六个字节后,紧接着下一个字节是CRC校验数据,用户可以根据需要读出,如果接收端需要CRC校验,则在接收完第六个字节后发ACK应答,否则发NACK结束,CRC初始值为0XFF,CRC8校验多项式 CRC[7:0]=1+x + x + x 4 5 8

计算温湿度:
在这里插入图片描述

三、CubeMX创建工程相关配置

开启I2C1
在这里插入图片描述
开启串口:
在这里插入图片描述
时钟配置
在这里插入图片描述

工程管理:
在这里插入图片描述
生成代码

四、代码编写

(1)自定义编写aht20.h和aht20.c文件

在工程目录/Core/Inc下创建aht20.h头文件
在这里插入图片描述

#ifndef INC_AHT20_H_
#define INC_AHT20_H_

#include "i2c.h"
//函数声明
void AHT20_Init(void);
void AHT20_Read(float *Temperature, float *Humidity);
#endif

在工程目录/Core/src下创建aht20.c文件
代码如下:

#include "aht20.h"

#define AHT20_ADDRESS 0x70 //{0x38,0}

uint32_t HAL_MAX_DALAY = 0xffff;

void AHT20_Init(void)
{
	uint8_t readBuffer;
	HAL_Delay(40);
	HAL_I2C_Master_Receive(&hi2c1,AHT20_ADDRESS,&readBuffer,1,HAL_MAX_DALAY);
	if((readBuffer & 0x08) == 0x00) //判断校验状态字
	{
		uint8_t sendBuffer[3] = {0xBE,0x08,0x00};
		HAL_I2C_Master_Transmit(&hi2c1,AHT20_ADDRESS,sendBuffer,3,HAL_MAX_DALAY);
	}
	HAL_Delay(20);
}

void AHT20_Read(float *Temperature, float *Humidity)
{
	
	uint8_t sendBuffer[4] = {0xAC,0x33,0x00,0x71};
	uint8_t readBuffer[6];
	
	HAL_I2C_Master_Transmit(&hi2c1,AHT20_ADDRESS,sendBuffer,3,HAL_MAX_DALAY); //发送触发测量命令
	HAL_Delay(80);
	HAL_I2C_Master_Receive(&hi2c1,AHT20_ADDRESS,readBuffer,6,HAL_MAX_DALAY);
	
	
	if(readBuffer[0] & 0x80 == 0x00)//判断忙状态bit[7]是否为0;
	 {

		 uint32_t data = 0;
		 //位拼接,提取湿度度数据
		 data = ((uint32_t)readBuffer[3] >> 4) + ((uint32_t)readBuffer[2] << 4) + ((uint32_t)readBuffer[1] << 12);
		 *Humidity = data * 100.0f / (1<<20);
		 data = ((uint32_t)readBuffer[3] & 0x0F << 16) + ((uint32_t)readBuffer[4] << 8) + (uint32_t)readBuffer[5] ;
		 *Temperature = data * 200.0f / (1<<20) - 50;
		 
     }
	 
}

(2)主函数

int main(void)
{

  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART1_UART_Init();
  AHT20_Init();
  float temperature  , humidity ;

  while (1)
  {
       AHT20_Read(&temperature,&humidity);
        printf("温度:%1.f ℃\r\n" ,temperature);
	    printf("湿度:%1.f %%\r\n" ,humidity);
	   HAL_Delay(1000);
  }
}

五、上板验证

在这里插入图片描述

总结

本次实验,学习了iic通信协议,以及实操iic协议与温湿度模块通信,采集环境温湿度信息。观察实验结果,对于温湿度的数据真实性存在怀疑态度,并且会有异常数据,目前正思考原因,后续就针对如何提高数据准确性进行改进。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值