使用STM32F103采集Si7021温湿度传感器数据

2019.06.13 更新

最近弄了个GitHub仓库,想要下载源码但又不想弄积分的朋友可以直接到我的GitHub上克隆

https://github.com/ZZZ-XXJ/Si7021-STM32F103.git


此采集程序是跑在STM32F103C8T6上的,模拟IIC接口读取数据,每50ms采集一次数据,每隔1s通过串口1发送一次数据,完整的Keil5工程文件和传感器驱动代码可在此下载:Si7021温湿度STM32F1读取程序

一、传感器电路连接

Si7021的外围电路非常简单,如图1所示:

图1    Si7021传感器外围电路

Si7021采用的是IIC接口,最高支持400KHz的通信速率,0~100%RH的湿度量程和最大-40℃~+125℃的温度量程,150μA低功耗,超小体积。可提供精确,低功耗,工厂校准的数字解决方案,适用于测量湿度,露点和温度,适用于从HVAC / R和资产跟踪到工业和消费者平台的各种应用。

二、时序和协议分析

首先看看Si7021的IIC通信时序,图2展示了Si7021的IIC时序图和各个时序时间的参数表。

图2    传感器IIC通信时序

其实这个IIC时序我个人认为没啥特别的,感觉就是一个比较常见的通信时序。

不过,这个传感器在读写协议上有个比较特殊的也是我有点搞不懂的地方。它的IIC读写其实是有两个模式的,一个叫保持主模式(Hold Master Mode),另一个叫无保持主模式(No Hold Master Mode),这两种模式又分别有两种测量指令相对应。

按照数据手册的说法,无保持主模式下在从机应答了测量指令后,主机要重新发送一次起始信号Sr,然后连续发送三次从机地址之后开才始读取数据;而在保持主模式下,传感器应答主机的读指令之后从机会把时钟线SCL强制拉高,直到温湿度转换完成。图3和图4分别为Si7021无保持主模式和保持主模式下的IIC读写协议。

图3    无保持主模式读写协议

图4    保持主模式读写协议

这个读写协议我就有点看不懂了,而且最尴尬的是,按照手册上的无保持主模式读写根本读不出数据,全是0xFF,而且不知道是不是我的驱动有问题,用保持主模式的时候拿逻辑分析仪测信号,发现SCL也并没有强制拉高。最后实在没办法,就用了无保持的测量指令,然后在STM32等到ACK之后延时20ms再读数据,才正常的。但是这样又跟数据手册说的完全不一样了。

反正当时真是把我给搞懵逼了,还请各位大佬能点拨指导一下。

三、测量程序编写

既然已经能读到数据了,那就直接开始编写测量程序好了。我的测量代码的底层IIC驱动代码是借鉴的正点原子的例程,温湿度计算部分参考了这篇博客:家庭IOT监测之温湿度SI7021及上传ONENET

首先是IO口的初始化,我使用了PB8(SCL)和PB9(SDA)。

void IIC_Init(void)//IIC初始化
{                        GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;//PB8->SCL, PB9->SDAGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);IIC_SCL=1;//初始电平设为高IIC_SDA=1;
}

然后是多字节读取传感器函数:

//函数名称:Multiple_read_Si7021
//函数功能:多字节读取传感器
//参数描述:
//返 回 值:
void Multiple_read_Si7021(u8 REG_address, u16 *value)
{u8 Si7021_BUF[2]={0};//缓存数组定义IIC_Start();//IIC起始信号IIC_Send_Byte((SLAVE_ADDR<<1)|0);//将7位器件地址左移一位再加上一位写操作IIC_Wait_Ack();//等待应答IIC_Send_Byte(REG_address);IIC_Wait_Ack();//等待应答delay_ms(19);//等待温湿度转换完成,至少应该大于18msIIC_Start();IIC_Send_Byte((SLAVE_ADDR<<1)|1);//将7位器件地址左移一位再加上一位读操作IIC_Wait_Ack();  Si7021_BUF[0] = IIC_Read_Byte(1);//读传感器高8位数据并发送应答信号Si7021_BUF[1] = IIC_Read_Byte(0);//读传感器低8位数据并发送非应答信号IIC_Stop();//停止信号*value=((Si7021_BUF[0]<<8)+Si7021_BUF[1]);//将高低8位数据合成为16位数据
}

接着是温湿度测量函数:

//函数名称:measure_si7021
//函数功能:NO HOLD MASTER模式下读取温湿度
//参数描述:无
//返 回 值:无
void measure_Si7021(void)
{//缓存变量定义u16 TEMP,HUMI;u8 curI;//读取温度Multiple_read_Si7021(TEMP_NOHOLD_MASTER,&TEMP);//NOHOLD_MASTER模式下读取温度si7021.temp=(((((float)TEMP)*175.72f)/65536.0f) - 46.85f);//将原始温度数据计算为实际温度数据并传递给缓存区,单位 ℃
//  TEMP_buf=(((((float)TEMP)*175.72f)/65536.0f) - 46.85f);Multiple_read_Si7021(HUMI_NOHOLD_MASTER,&HUMI);//NOHOLD_MASTER模式下读取湿度si7021.humi=(((((float)HUMI)*125.0f)/65535.0f) - 6.0f);//将原始湿度数据计算为实际湿度数据并传递给缓存区,单位 %RH
//  Humi_buf=(((((float)HUMI)*125.0f)/65535.0f) - 6.0f);//下面其实是我抄的机智云智能宠物屋温湿度测量的一个平均值滤波算法,循环储存10次的数据,调用一次measure_Si7021()就存一次if(MEAN_NUM > si7021_filter.curI)//当MEAN_NUM==10时,完成10次读取{si7021_filter.tBufs[si7021_filter.curI] = si7021.temp;si7021_filter.hBufs[si7021_filter.curI] = si7021.humi;si7021_filter.curI++;}else{si7021_filter.curI = 0;si7021_filter.tBufs[si7021_filter.curI] = si7021.temp;si7021_filter.hBufs[si7021_filter.curI] = si7021.humi;si7021_filter.curI++;}if(MEAN_NUM <= si7021_filter.curI) {si7021_filter.thAmount = MEAN_NUM;}//判断是否初次循环if(0 == si7021_filter.thAmount) {//计算采集第10次数据之前的平均值for(curI = 0; curI < si7021_filter.curI; curI++){si7021.temp += si7021_filter.tBufs[curI];si7021.humi += si7021_filter.hBufs[curI];}si7021.temp = si7021.temp / si7021_filter.curI;si7021.humi = si7021.humi / si7021_filter.curI; TEMP_buf = si7021.temp;Humi_buf = si7021.humi;}else if(MEAN_NUM == si7021_filter.thAmount) {//计算采集第10次数据之后的平均值for(curI = 0; curI < si7021_filter.thAmount; curI++) {si7021.temp += si7021_filter.tBufs[curI];si7021.humi += si7021_filter.hBufs[curI];}si7021.temp = si7021.temp / si7021_filter.thAmount; si7021.humi = si7021.humi / si7021_filter.thAmount; TEMP_buf = si7021.temp; Humi_buf = si7021.humi; }
}

最后,主函数每50ms调用一次测量函数,但每隔1s才发送一次数据给串口:

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "Si7021.h"int main(void)
{u8 i=0;delay_init();          //延时函数初始化   uart_init(115200);      //串口1初始化波特率为115200IIC_Init();               //IIC初始化 while(1){  //每50ms读取一次数据measure_Si7021();i++;delay_ms(50);if(i==20){   //串口每1s打印一次数据printf("\r\nTemp:%.2f\r\n",TEMP_buf);//打印温度数据,保留两位小数printf("Humi:%.2f\r\n",Humi_buf);//打印湿度数据,保留两位小数 i=0;}}
}    delay_init();           //延时函数初始化   uart_init(115200);      //串口1初始化波特率为115200IIC_Init();               //IIC初始化 while(1){  //每50ms读取一次数据measure_Si7021();i++;delay_ms(50);if(i==20){   //串口每1s打印一次数据printf("\r\nTemp:%.2f\r\n",TEMP_buf);//打印温度数据,保留两位小数printf("Humi:%.2f\r\n",Humi_buf);//打印湿度数据,保留两位小数 i=0;}}
}

使用STM32F103采集Si7021温湿度传感器数据相关推荐

  1. 【逗老师带你学IT】PRTG监控通过Python+Modbus RTU获取温湿度传感器数据

    前文[逗老师带你学IT]PRTG监控通过Python+TCP Modbus获取温湿度传感器数据中我们讲了如何通过Python读取支持TCP Modbus的传感器数据.本章我们讲解下如何读取Modbus ...

  2. 【逗老师带你学IT】PRTG监控通过Python+TCP Modbus获取温湿度传感器数据

    本文介绍,Python如何通过TCP Modbus协议获取温湿度传感器数据.并在PRTG监控系统中呈现. 本文主要涉及知识点: 1.Python的ModbusTCP客户端实现 2.常见温湿度传感器中, ...

  3. vb6编写dll读取dat文件_【STM32Cube_15】使用硬件I2C读取温湿度传感器数据(SHT30)...

    寻求更好的阅读体验,请移步Mculover666的个人博客: [STM32Cube_15]使用硬件I2C读取温湿度传感器数据(SHT30)​www.mculover666.cn 本篇详细的记录了如何使 ...

  4. 使用RT-Thread Studio DIY 迷你桌面时钟(二)| 获取温湿度传感器数据(I2C设备驱动+SHT3x软件包)

    寻求更清爽的阅读体验,请移步:Mculover666的个人博客. 1. 项目进度 桌面Mini时钟项目用来演示如何使用RT-Thread Stduio开发项目,整个项目的架构如下: 在上一篇博文中简单 ...

  5. 使用RT-Thread Studio DIY 迷你桌面时钟| 获取温湿度传感器数据(I2C设备驱动+SHT3x软件包)...

    1. 项目进度 桌面Mini时钟项目用来演示如何使用RT-Thread Stduio开发项目,整个项目的架构如下: 在上一篇博文中简单的介绍了RT-ThreadStudio一站式工具,基于STM32L ...

  6. Android手机HC-05蓝牙连接Arduino nano获取DHT-11温湿度传感器数据

    如果您觉得本文对您有用,希望您点赞,收藏并且把它分享出去,不明白的可以在评论区留言,我会一一解答,感谢您的支持!! 目标 Android手机HC-05蓝牙连接Arduino nano获取DHT-11温 ...

  7. 【STM32F767】使用RTThread和TouchGFX实现DIY数字仪表(三)——获取温湿度传感器数据

    目录: [STM32F767]使用RTThread和TouchGFX实现DIY数字仪表(一)--使用STM32CUBMX5.6移植touchGFX4.13 [STM32F767]使用RTThread和 ...

  8. MicroPython ESP32 读取DHT11温湿度传感器数据

    MicroPython ESP32 读取DHT11温湿度传感器数据 DHT11温湿度传感器 接线说明 ESP32 ----- DHT11 3.3V ----- VCC GND ----- GND GP ...

  9. Arduio ESP8266将DHT11温湿度传感器数据在网页上显示

    Arduio ESP8266将DHT11温湿度传感器数据在网页上显示

最新文章

  1. 目标检测--Improving Object Detection With One Line of Code
  2. C++ Code_ImageList
  3. java堆栈信息 linux_java - Java程序无法从Linux服务器远程读取文件 - 堆栈内存溢出...
  4. 需求评审五个维度框架分析及其带来的启示-5-结束语
  5. 通信 / 各种协议默认端口汇总
  6. 【ArcGIS风暴】ArcGIS自动生成标识码(BSM)的两种方法案例教程
  7. PyTorch 1.4 最新版放出:支持Python2的最后一版,支持分布式模型并行、Java程序、移动端等多项新功能...
  8. 截获3389远程登陆的密码
  9. 单例模式懒汉Java_java 单例模式(懒汉式与饿汉式)
  10. 如何快速离职?离职交接工作清单(前端)
  11. 游戏太难通关?教你用CE和Python写一个属于自己的植物大战僵尸修改器(无限阳光,无限金币,无冷却时间)
  12. 手游实时阴影方案之Projector Shadow
  13. 工作总结--如何定位web系统前后台的bug,以及bug分析/测试感想
  14. laravel 常用文档
  15. bzoj 4763: 雪辉
  16. 大图数据管理与分析技术(综述)
  17. TIA西门子博途V18安装教程及注意事项
  18. 在大数据和人工智能时代,我们是否需要分布式流处理?
  19. 相位解包裹 matlab,二维相位解包裹matlab
  20. python 私有属性_Python 私有属性和私有方法

热门文章

  1. java随机获取字母,Java程序获取随机字母
  2. 单片机c语言ad与da转换实验报告,单片机AD与DA转换实验报告.docx
  3. Unity的gamma矫正、颜色空间及其转换的问题
  4. 论文不记之《StyleNet: Generating Attractive Visual Captions with Styles》
  5. 可能是国内第一篇全面解读Java现状及趋势的文章
  6. 单片机炫彩灯实训报告_51单片机呼吸灯实验报告.doc
  7. 怎样用Excel搜索表格内的内容?
  8. [Leetcode学习-java]Additive Number
  9. RocketMQ延迟消息的代码实战及原理分析
  10. QQ看点内容中心存储系统介绍