I2C通信实例 - SHTx温湿度传感器 01

发布于:2023-01-09 ⋅ 阅读:(1108) ⋅ 点赞:(0)

        因科研中需要测量温度和湿度,打算自制了一个温湿度传感器。传感芯片采用的是SHT35,单片机为STM32F103ZET6。工作原理很简单,通过I2C接口向芯片发送指令和采集数据,然后通过USART发送到上位机。先来了解一下传感器。

1. 主要功能

  • 全面校准、线性、温度补偿数字输出
  • 宽电压工作范围:2.15V-5.5V
  • I2C通信接口,最高速度可达1MHz
  • 双地址可选。
  • 启动和测量速度快
  • 8针DFN封装,尺寸:2.5×2.5×0.9mm

a321f62a268f40c3acf25a3b0f98ba74.png

图1. 传感器内部功能模块框图

        传感器的功能框图如图1所示。内部有一个16位的ADC负责采集温度和湿度传感器的数据,然后通过校准和线性化处理,通过I2C接口与外部通信。整个模块有7个功能引脚:

引脚名称

功能说明

nRESET

硬件复位。输入低电平复位;不用时可浮空或通过>2KΩ电阻接到VDD。

VDD

电源正极。接2.15-5.5V,通常接3.3V。

VSS

电源负极。接地。

Alert

报警引脚。温湿度超过限定值时可输出报警信号。不用时必须浮空

SCL

时钟引脚。接主I2C模块同名引脚。

SDA

数据引脚。接主I2C模块同名引脚。

ADDR

地址引脚。通过该引脚电平高/低,选择模块的通信地址。不能浮空

914e3604573541e8af06e84ea0578e4a.png

 图2. 传感器芯片典型接线图。

        典型接线图如图2所示。R引脚是个空引脚,无电气功能。VDD必须通过一个100nF的电容接地。SCL和SDA需要通过上拉电阻接到VDD。从网上买的焊接好的模块(右下角所示),只引出了6个引脚,nRESET被直接连到了VDD,SCL和SDA的两个上拉电阻均为10kΩ的贴片电阻。另外,Alert引脚也通过一个贴片电容接地,ADDR引脚接了一个10k欧的下拉电阻。模块到手价53,还是比价厚道的价格,SHT35价格还是比较高的,零售价在30元上下。

2. 工作原理

        SHT35是I2C接口。工作原理很简单:将MCU的I2C设为Master,芯片的I2C作为Slave,每次读写前,Master首先向Slave发送地址,收到确认信号后再发送(设置、测量、读取等)指令。对读取指令返回的原始数据进行处理、显示或发送到上位机。

        根据芯片手册,SHT35有两个地址ADDR引脚接低电平时,默认地址是0x44ADDR接高电平时,地址是0x45。这种设计使得多个芯片可以连接到同一条总线上工作,通过ADDR引脚(接GPIO)进行片选。这款芯片采用的是I2C的7-bit地址标准。以ADDR接地为例:写入请求时须将地址左移1位,末位为0,即0x44<<1U;读取请求时,须左移1位然后将末位置1,即(0x44<<1U) | 0x1。这个细节极其重要,否则会因地址错误,导致传感器无应答。

        SHT35带CRC校验,所有指令都自带CRC。从机发送数据时,都会计算CRC。完整的读取温度和湿度信息需要6个字节:前2个字节为温度原始数据,第3个为温度数据的CRC,第4-5个字节为湿度原始数据,第6个字节为湿度数据的CRC。如果不需要CRC,软件中可以不进行CRC校验,但SHT35内部是一定会计算和发送CRC的。

所谓的读写指令,就是芯片厂商设计好的一组16位代码。详见下文。

3. 工作模式

1) 单次测量模式:

76212ca18b5e47c09200fc5646ead96b.png

图3. 单次测量模式相关指令

        所谓单次测量(Single shot)模式,就是发一次指令,读一次数据。根据主I2C是否开启时钟延长和测量可靠性高、中、低(平均次数)不同,共有6组指令。如图3所示。

2) 周期性测量模式

5213518c651e44ae9e5eb052a634b536.png

图4. 周期性测量指令

         所谓周期性测量(Periodic data acquisition)模式,就是发一次测量指令,可以周期性地读取数据。根据可靠性和测量频率(0.5Hz-10Hz)不同,共有15组指令。如图四所示。

        周期性测量模式下,发送测量指令后,每次读取数据前必须发送Fetch Data指令:0xE000。周期测量模式下,可以发送ART(Accelerated Response Time)指令:0x2B32进行加速,该指令会强制芯片以4Hz的速度获取数据。

        退出周期模式,需发送Break指令:0x3093。退出后芯片会回到单次测量模式。

3) 报警模式

        SHT3x系列芯片提供了一个报警模式。在周期性测量模式下,可以利用Alert引脚来监控温湿度是否超过了预设的阈值。如果超过了阈值,Alert引脚的电平会发生变化,同时内置的16-bit状态寄存器的标志位会对报警原因进行标识。比如可以将Alert引脚连接到MCU的中断引脚,当出现环境参数超限时,可以用来唤醒MCU,查询传感器内部状态寄存器确定原因,然后通过外围电路进行相应的响应,例如发出声音、闪灯、提示等。

        温度和湿度的报警阈值分别由4个阈值构成。如图5所示:

94d7cca2c7df4a378c8de4bc269a9560.png

图5. 报警模式的不同阈值

  • HIGH Set:上限报警值。高于该值启动报警,ALERT引脚输出高电平。
  • HIGH Clear:清除上限报警值。高于HIGH Set后,回落至该值以下,清除报警。
  • LOW Set:下限报警值。低于该值触发报警,ALERT引脚输出高电平。
  • LOW Clear:清除下限报警值。低于LOW Set后,回升至该值以上,清除报警。

这种设计可以避免在报警值附近出现快速振荡。

        阈值的设置通过向传感器写入一个16-bit的数据来实现,其中高7位为湿度阈值,第9位为温度阈值。由于温度和湿度值也是以16-bit格式来表示的,设置阈值时原始数据与阈值数据的对应关系如图6所示:

3c3c7f7e0b344f7b8739759f45187821.png

图6. 原始数据拼成阈值数据的方法

 即,截取湿度值的高7位作为阈值的高7位、温度值的高9位作为阈值的低9位。用程序表示如下:

limitVal = (rawHumidity&0xFE00)|((rawTemperature>>7)&0x001FF);

拼成一个16-bit的值后,用一个命令即可完成设置,可以提高效率。设置阈值时,温度的分辨率约0.5℃,湿度分辨率约1%。

        前述4种阈值均按相同的格式进行设置。具体是哪种阈值,则由读/写前的引导命令代码来区分。读和写入阈值的指令代码如图7所示:

ae5b996f540e4d6491832f232dbc4af7.png

图7. 读、写报警阈值的指令代码

 复位后,报警阈值会恢复图8所示的初始值。

8612d50575b24b00afa3dae6e3ce2d8a.png

图8. 报警阈值初始值

 特别注意:写入报警阈值时,发送地址后,指令(2bytes)、数据(2bytes)、CRC(1byte)要依次发送过去。发送数据前不能再发送地址。换言之,用HAL_I2C_Master_Transmit函数要一次性发送5个字节。

4) 状态寄存器

        传感器芯片内置了一个16-bit的状态寄存器。各功能位释义如下:

功能说明

默认值

15

报警挂起

0-无挂起报警

1-至少有一个挂起报警

1

14

预留

0

13

加热器状态

0-关闭

1-开启

0

12

预留

0

11

RH报警追踪

0-无湿度报警

1-有湿度报警

0

10

T报警

0-无温度报警

1-有温度报警

0

9:5

预留

00000

4

是否检测到系统复位

0-自上次清除状态寄存器后无复位

1-自上次清除状态寄存器后有复位

1

3:2

预留

00

1

命令状态

0-上一命令成功执行

1-上一命令未执行(无效/CRC不匹配)

0

0

CRC写入状态

0-上次CRC写入正确

1-上次CRC写入失败

0

        状态读取指令:0xF32D。

        状态寄存器复位指令:0x3041。清除所有状态位(置0)。

5) 其它指令

        软件复位指令:0x30A2。该指令使芯片控制器复位并重新加载校准数据。

        加热器开/关指令:0x306D/0x3066。内部加热器,仅供芯片测试使用。

        另外还有预警阈值设置等。详见手册或官方例程,不再赘述。


搞懂了硬件的工作原理,接下来基于HAL库编写驱程。

后文链接:

本文含有隐藏内容,请 开通VIP 后查看