FPGA实验记录五:I2C读取AHT10温湿度传感器
一、AHT10温湿度传感器
1. 简介
AHT10,新一代温湿度传感器在尺寸与智能方面建立了新的标准:它嵌入了始于回流焊的双列扁平无引脚SMD封装,底面4*5mm,高度1.6mm。传感器输出经过标定的数字信号,标准I²C格式。
AHT10配有一个全新设计的ASIC专用芯片、一个经过改进的MEMS半导体电容式湿度传感元件和一个标准的片上温度传感元件,其性能已经大大提升甚至超出了前一代传感器的可靠水平,新一代温湿度传感器,经过改进使其在恶劣环境下的性能更加稳定。
每一个传感器都经过校准和测试,在产品表面印有产品批号。由于对传感器做了改良和微型化改进,因此它的性价比更高,并且最终所有设备都将得益尖端的节能运行模式。
I2C总线上仅能连接一个AHT10,连上后便不再支持其他I2C部件。
2. 传感器性能
3. 布线规则和信号完整性
如果SCL和SDA信号线相互平行且非常接近,有可能导致信号串扰和通讯失败。解决方法是在两个信号线之间放置VDD/GND,将信号线隔开,或使用屏蔽电缆。此外,降低SCL频率也可能提高信号传输的完整性。须在电源引脚VDD/GND之间加一个10μF的去耦电容,用于滤波。次电容应尽量靠近传感器。
此外,为了提高传感器的可靠性,电路板在layout时避免在传感器底部布线或覆盖设计。
针对本次实验而言,这里的10μF去耦电容不需要理会,在此贴出只是为了文章的严谨性。
4. 接口定义
- VDD、GND电源引脚:AHT10的供电范围为1.8-3.6V,推荐电压为3.3V。
- SCL串行时钟:用于微处理器(FPGA)与AHT10之间的通讯同步。由于接口包含了完全静态逻辑,因而不存在最小SCL频率。
- SDA串行数据:用于传感器的数据输入和输出。
- 当向传感器发送命令时,SDA在串行时钟SCL的上升沿有效,且当SCL为高电平之后,SDA必须保持稳定。在SCL下降沿之后,SDA值可被改变。
SDA的有效时间在SCL上升沿之前的TSU和下降沿之后的TH0。
- 当从传感器读取数据时,SDA在SCL变低以后有效,且维持到下一个SCL下降沿。(标准I2C)
- 当向传感器发送命令时,SDA在串行时钟SCL的上升沿有效,且当SCL为高电平之后,SDA必须保持稳定。在SCL下降沿之后,SDA值可被改变。
5. 命令与时序
每个传输序列都以Start状态作为开始,并以Stop状态结束。(I2C格式)
命令 | 释义 | 二进制 | 十六进制 |
---|---|---|---|
首字节 | 包含设备地址的读写控制字(Read:1,Write:0)。 | 0111_000x | 0x38<<1 + 1/0 |
查看状态字/读取测量值 | 实际上是读控制字,意味着在非触发测量时,可以读取状态字;触发测量后80ms可以读取1个状态字+温湿度值共5个字 | 0111_0001 | 0x71 |
初始化字 0XE1 | 初始化传感器各种状态,拥有两个命令参数字节,分别是0x08和0x00。 | 1110_0001&0000_1000&0 | 0XE1&0x08&0x00 |
触发测量 0xAC | 读取温湿度,拥有两个命令参数字节,分别是0x33和0x00。 | 1010_1100&0011_0011&0 | 0xAC&0x33&0x00 |
软复位 0XBA | 用于在无需关闭和再次打开电源的情况下,重新启动传感器系统。接收到此命令后传感器系统开始重新初始化,并恢复默认设置状态,软复位所需时间不超过20ms。 | 1011_1010 | 0xBA |
传感器读取流程:
-
上电后等待40ms,读取温湿度值之前,首先要看状态字节的校准时能Bit[3]是否为1(通过发送0x71可以获取1个字节的状态字),如果不为1,要发送0XE1命令以及两个参数0x08和0x00。
命令参数什么意思?我这里可以从函数的角度去看他,理解为0XE1(0X08,0X00)。即只发送一个函数名还不行,还需要两个参数传递进去才能触发它应有的功能。那只能传递这两个参数吗?有其他的吗?目前在手册上还没有发现其他参数。
- 直接发送0xAC命令与相应的命令参数0x33和0x00来触发测量。
- 等待80ms,发送读控制字读取状态和测量值。(一共6字节,其中状态1字节,温湿度各2.5字节)
软复位:
6. 信号转换
相对湿度转换:
相对湿度RH都可以根据SDA输出的相对湿度信号**SRH[19:0]**通过如下公式计算获得
(结果以%RH表示)
温度转换:
温度T都可以通过将温度输出信号**ST[19:0]**带入到下面的公式计算得到
(结果以℃表示)
二、I2C协议
关于I2C的相关知识,我上一篇博客已经写的很清楚了,可以参考FPGA基础协议二:I2C读取E2PROM
三、逻辑设计
1. 实验要求:
通过I2C协议使用FPGA读取AHT10所测定的温湿度值。
2. 设计思路:
总体需求:使用FPGA通过串口和I2C协议将AHT10测定的温湿度值传递到上位机中进行显示。
测量温湿度流程:
-
上电后等待40ms
-
发送 读取状态命令
0X71
然后接收状态字
; -
如果状态字校验位bit[3]!=1,则发送
起始位
+写控制字
+ 初始化命令0XE1(0x08,0x00)
+停止位
,否则跳过此步;校准位检验在上电时检查即可,后面便可以不再检查。
-
发送
起始位
+写控制字
+ 触发测量命令0XE1(0X33,0X00)
+停止位
; -
等待80ms;
-
发送
起始位
+读控制字
,然后等待接收状态数据以及温湿度数据,接收完6字节后发送停止位
; -
将温湿度数据进行信号转换,然后通过串口发送到上位机中进行展示;
-
重复5-7步骤。
**或者,**也可以非常粗鲁地跳过第2步,直接执行1,3–8步骤,因为初始化化后校验位必为1,这样就可以省略很多不必要的流程。
本次实验也将跳过第2步来简化操作。
模块设计:
- 需要一个ATH读写控制模块,来控制命令发送;
- 需要一个I2C接口模块来讲数据进行I2C协议格式的转换;
- 需要一个IO_CTRL模块来控制SDA的输入输出状态;
- 需要一个Data_driver数据处理模块,来讲数据信号进行合理转换;
- 需要一个Uart_Tx模块来讲数据发送给上位机,同时配备一个fifo来暂存发送字节;
3. 模块框图:
uart_tx: 串口发送模块,用于将程序存于rdfifo中的温湿度数据并串转换后发送给上位机进行展示;
aht10_rwctrl: AHT10读写控制模块,用来向AHT10温湿度传感器发送命令,以及处理i2c接口模块接收到并串并转换后的数据,比如将温湿度字节根据公式进行信号转换后存入data_driver中进行处理;
data_driver: 数据处理模块,用于将从AHT10读取的温湿度数据处理切割成数个字节,使其通过串口打印在上位机时符合精度要求;
i2c_interface:i2c接口模块,用来把接收到的指令并串转换为I2C协议的格式然后传输到AHT10存储器中,或将AHT10传输回来的信息进行串并转换传回到rwctrl模块中;
io_ctrl: SDA总线控制模块,负责控制这根inout双向数据总线何时input,何时output。(对data_driver而言没有太大的关系,把data_driver放在里面只是为了方便接收rwctrl模块出来的数据)
4. 状态机:
负责产生时钟的是主状态机,这里i2c接口模块负责控制SCLK,即产生时钟。
主状态机:
-
IDLE:空闲状态,这个时候
SCL
与SDA
都为高电平,等待主状态机的命令。 -
START:发送起始位,此时
SDA
将在SCL
处于高电平时拉低。起始位只存在于读写控制字之前,往