STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出
学习I2C总线通信协议,使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出。
文章目录
前言
- 学习I2C总线通信协议,使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出。具体任务:
1)解释什么是“软件I2C”和“硬件I2C”? (阅读野火配套教材的第23章“I2C–读写EEPROM”原理章节)
2)阅读AHT20数据手册,编程实现:每隔2秒钟采集一次温湿度数据,并通过串口发送到上位机(win10)。
一、I2C总线通信协议
1.I2C总线
- I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
- 主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。
- I2C 总线接口连接微控制器和串行 I2C 总线。它提供多主机功能,控制所有 I2C 总线特定的时序、协议、仲裁和定时。支持标准和快速两种模式,同时与 SMBus 2.0 兼容。I2C 总线有多种用途,包括 CRC 码的生成和校验、SMBus(系统管理总线 System Management Bus)、PMBus(电源管理总线 Power Management Bus)。根据特定设备的需要,可以使用 DMA 以减轻 CPU 的负担。
2.工作原理
SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,接口电路为开漏输出。需通过上拉电阻接电源VCC。
当总线空闲时,两根线都是高电平,连接总线的外同器件都是CMOS器件,输出级也是开漏电路。在总线上消耗的电流很小,因此,总线上扩展的器件数量主要由电容负载来决定,因为每个器件的总线接口都有一定的等效电容。而线路中电容会影响总线传输速度。当电容过大时,有可能造成传输错误。所以,其负载能力为400pF,因此可以估算出总线允许长度和所接器件数量。
主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件。在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件。然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下。主机负责产生定时时钟和终止数据传送。

I2C模块接收和发送数据,并将数据从串行转换成并行,或并行转换成串行。可以开启或禁止中断。接口通过数据引脚(SDA)和时钟引脚(SCL)连接到I2C总线。允许连接到标准(高达100kHz)或快速(高达400kHz)的I2C总线。
注意:IIC是为了与低速设备通信而发明的,所以IIC的传输速率比不上SPI
3.I2C特点
● 并行总线/I2C 总线协议转换器
● 多主机功能:同一接口既可做主设备也可做从设备
● I2C 主设备功能
− 产生时钟
− 产生起始和停止信号
● I2C 从设备功能
− 可编程的 I2C 地址检测
− 可响应 2 个从地址的双地址能力
− 停止位检测
● 产生和检测 7 位/10 位地址和广播呼叫
● 支持不同的通讯速度
− 标准速度(高至 100 kHz)
− 快速(高至 400 kHz)
● 状态标志:
− 发送器/接收器模式标志
− 字节发送结束标志
− I2C 总线忙标志
● 错误标志
− 主模式时的仲裁丢失
− 地址/数据传输后的应答(ACK)错误
− 检测到起始和停止错位
− 禁止拉长时钟功能后的上溢或下溢
● 2 个中断向量
− 1 个中断用于地址/数据通讯成功
− 1 个中断用于出错
● 可选的拉长时钟功能
● 具单字节缓冲器的 DMA
● 可配置的 PEC(信息包错误检测)的产生或校验:
− 发送模式中 PEC 值可以作为最后一个字节传输
− 用于最后一个接收字节的 PEC 错误校验
● 兼容 SMBus 2.0
− 25 ms 时钟低超时延时
− 10 ms 主设备累积时钟低扩展时间
− 25 ms 从设备累积时钟低扩展时间
− 带 ACK 控制的硬件 PEC 产生/校验
− 支持地址分辨协议(ARP)
● 兼容 SMBus
4.I2C模式选择
● 从发送器模式
● 从接收器模式
● 主发送器模式
● 主接收器模式
- 默认模式为从模式。接口在生成起始条件后自动从从模式切换到主模式;当仲裁 丢失或产生停止信号,则从主模式切换到从模式。允许多主机功能。
- 主模式时,I2C 接口启动数据传输并产生时钟信号。串行数据传输总是以起始条
件开始和停止条件结束。主模式时,由软件控制产生起始条件和停止条件。 - 从模式时,I2C 接口能识别它自己的地址(7 位或 10 位)和广播呼叫地址。软件控 制开启或禁止广播呼叫地址的识别。
- 数据和地址按 8 位/字节进行传输,高位在前。跟在起始条件后的第一、二个字节
是地址(7 位模式为 1 个字节,10 位模式为 2 个字节)。地址只在主模式发送。 - 在一个字节传输的 8 个时钟后的第 9 个时钟期间,接收器必须回送一个应答位 (ACK)给发送器。
参考下图

软件可以开启或禁止应答(ACK),I2C 接口的地址(7 位、10 位地址或广播呼叫地
址)可通过软件设置。
I2C接口的功能框图

5.软件I2C和硬件I2C
硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活。
-
软件I2C:软件IIC通信指的是用单片机的两个I/O端口模拟出来的IIC,用软件控制管脚状态以模拟I2C通信波形,软件模拟寄存器的工作方式。
直接使用 CPU 内核按照 I2C 协议的要求控制 GPIO 输出高低电平,从而模拟I2C。 -
硬件I2C:一块硬件电路,硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,硬件(固件)I2C是直接调用内部寄存器进行配置。
直接利用 STM32 芯片中的硬件 I2C 外设。
二、串口输出温湿度传感器的数据
1.核心代码分析
- AHT20芯片的使用过程read_AHT20_once函数:
代码如下
void read_AHT20_once(void)
{
delay_ms(10);
reset_AHT20();//重置AHT20芯片
delay_ms(10);
init_AHT20();//初始化AHT20芯片
delay_ms(10);
startMeasure_AHT20();//开始测试AHT20芯片
delay_ms(80);
read_AHT20();//读取AHT20采集的到的数据
delay_ms(5);
}
- AHT20芯片读取数据 read_AHT20函数
代码如下
void read_AHT20(void)
{
uint8_t i;
for(i=0; i<6; i++)
{
readByte[i]=0;
}
I2C_Start();//I2C启动
I2C_WriteByte(0x71);//I2C写数据
ack_status = Receive_ACK();//收到的应答信息
readByte[0]= I2C_ReadByte();//I2C读取数据
Send_ACK();//发送应答信息
readByte[1]= I2C_ReadByte();
Send_ACK();
readByte[2]= I2C_ReadByte();
Send_ACK();
readByte[3]= I2C_ReadByte();
Send_ACK();
readByte[4]= I2C_ReadByte();
Send_ACK();
readByte[5]= I2C_ReadByte();
SendNot_Ack();
//Send_ACK();
I2C_Stop();//I2C停止函数
//判断读取到的第一个字节是不是0x08,0x08是该芯片读取流程中规定的,如果读取过程没有问题,就对读到的数据进行相应的处理
if( (readByte[0] & 0x68) == 0x08 )
{
H1 = readByte[1];
H1 = (H1<<8) | readByte[2];
H1 = (H1<<8) | readByte[3];
H1 = H1>>4;
H1 = (H1*1000)/1024/1024;
T1 = readByte[3];
T1 = T1 & 0x0000000F;
T1 = (T1<<8) | readByte[4];
T1 = (T1<<8) | readByte[5];
T1 = (T1*2000)/1024/1024 - 500;
AHT20_OutData[0] = (H1>>8) & 0x000000FF;
AHT20_OutData[1] = H1 & 0x000000FF;
AHT20_OutData[2] = (T1>>8) & 0x000000FF;
AHT20_OutData[3] = T1 & 0x000000FF;
}
else
{
AHT20_OutData[0] = 0xFF;
AHT20_OutData[1] = 0xFF;
AHT20_OutData[2] = 0xFF;
AHT20_OutData[3] = 0xFF;
printf("读取失败!!!");
}
printf("\r\n");
//根据AHT20芯片中,温度和湿度的计算公式,得到最终的结果,通过串口显示
printf("温度:%d%d.%d",T1/100,(T1/10)%10,T1%10);
printf("湿度:%d%d.%d",H1/100,(H1/10)%10,H1%10);
printf("\r\n");
}
完整代码可从我的gitee网址下载:
https://gitee.com/caidongqi/embedded-system-development/tree/master/AHT20
2.硬件实操连接
2.1 USB转TTL
3v3—3v3,GND—GND,RXD—A9,TXD—A10
2.2 温湿度传感器

将SDA和PB7,SCL和PB6连接
注意正反面,1接3v3,3接GND,不要接反,否则直接芯片g!
3.最终结果演示
- 打开Flymcu进行烧录

-
打开串口调试助手


-
结果演示
AHT20
总结
本篇博客主要简略介绍了I2C总线通信协议,使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出。而且并对硬件I2C和软件I2C进行了一个简短介绍。
此次实操过程中,我发现了许多问题,代码烧录进去后,串口调试后却发现从温湿度传出来的温度-湿度都为0,结果经老师提醒发现可能是由于电压不够的情况,最好给予5伏左右的电压。且要注意连线时候的接触不良情况,有时会导致不能烧录,有时候烧录成功也不能运行。
希望大家多多给出意见,欢迎交流!
参考: https://blog.csdn.net/qq_43279579/article/details/111597278
https://blog.csdn.net/qq_46467126/article/details/121436790?spm=1001.2014.3001.5502
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)