一、导言

SHT30温湿度传感器模块是通过IIC驱动,所以大家使用该模块时,需要具备IIC的基本知识,这篇文章带领大家一起使用SHT30模块进行温湿度的测量,当然DHT10/DHT10原理都一样,好了,一起来学习学习吧!

二、IIC知识

1、IIC总线介绍

I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。I2C总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。由于其管脚少,硬件实现简单,可扩展性强等特点,因此被广泛的使用在各大集成芯片内。下面我们就从IIC的物理层和协议层来了解IIC

1.1、IIC物理层


物理层:
(1)它是一个支持多设备的总线
(2)I2C 总线只使用两条总线线路,SDA、SCL。
(3)每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。
(4)总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
(5)多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。
(6)具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式下可达 3.4Mbit/s,但目前大多 I2C 设备尚
不支持高速模式。
(7)连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制。

1.2、IIC协议层

(1)数据有效性规定

如上图可以看到,当时钟线SCL为高电平时,并且SDA为高电平时,数据要求稳定,即不允许变化,SCL为高电平就是SDA的载体,当时钟线SCL为低电平时,这时候允许SDA的数据发生变化,即可以允许数据传送,所以通过时序图我们就能很好的进行编程,很容易上手IIC。(注意:每次传输都以字节为单位)
(2)开始信号和停止信号

如上图可以看到,当时钟线SCL为高电平时,并且SDA由高电平变为低电平,这时候表明已经启动了IIC,后面我们在程序中也是这样去进行设计,非常方便,灵位当时钟线SCL为高电平,并且SDA由低电平变为高电平,这时候表明已经停止了IIC。从这里大家可以看到,不管是开始IIC还是停止IIC,时钟线都是保持高电平才行,只有SDA的电平有变化。
(3)应答(ACK)与非应答信号(NACK)

如上图可以看到,当IIC启动之后,就开始传输数据,前面说过IIC传输是以字节为单位进行传输,例如一个字节8位,那么首先IIC先将8位进行传输,传输完成之后,后面紧跟着第9位,表示应答位,什么意思呢?也就是说只要一个字节8位必须正确按位传输,当传输完成之后,从机就会响应数据是否传输正确,如果正确,则从机响应应答信号,将SDA置为低电平表示应答,如果传输错误从机响应非应答信号,将SDA置为高电平,主机产生一个终止信号,终止本次数据的传输,然后主机再开启下一次传输。所以通过这个时序图可以看出,每一个字节传输完成之后,后面都需要紧跟着一个应答位/非应答位。
(4)总线的寻址方式
总线的寻址方式一般有两种,一种是7位寻址,另一种是10位寻址,通常采用7位进行寻址,也就是传输设备的地址是7位,7位寻址时序图如下:

如上图可以看到,总线传输是以字节传输,当以7位寻址的时候,前7位表示从机地址,第8位表示主机是写还是读;首先要清楚为什么要寻址(7位)?前面讲过,挂接在IIC总线上的设备有很多,这时候总线就会为挂接在总线上的设备分配唯一的地址,类似于路由器给连接在路由器上的WIFI设备分配不同且唯一的IP地址,所以主机就可以根据地址跟不同的设备进行通信,讲清楚了前7位,然后讲第8位;第8位表示从机是从主机接收数据,还是向主机写数据。
(5)总线的数据传输方式
I2C总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/W),用“0”表示主机发送(写)数据(W),“1”表示主机接收数据(R)。每次数据传送总是由主机产生的终止信号结束。但是,若主机希望继续占用总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对另一从机进行寻址。如下所示:S表示IIC开始信号,0表示主机写入从机,1表示主机从从机读取,A表示应答信号,非A表示非应答信号,P表示停止信号
第一种传输方式:主机向从机发送数据,数据传输方向在整个传输过程不变

第二种传输方式:主机在传输第一个字节后,立即从从机读取数据

第三种传输方式:在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重
复产生一次,但两次读/写方向位正好反相

三、SHT30源代码

1、sht30.c源文件

/*
设定温度阈值范围:-20℃——125℃
设定相对湿度范围:0%——100%
*/
#include"stm32f10x.h"
#include"sht30.h"
#include"stdio.h"#define write 0 //IIC设备地址一般是7位,也有10位,本程序使用7位IIC设备地址,第8位是写命令
#define read  1 //IIC设备地址一般是7位,也有10位,本程序使用7位IIC设备地址,第8位是读命令//IIC总线接口定义
#define SCL PBout(6)//设置时钟端口
//SHT30数据SDA传输口,有输出也有输入,所以需配置它的输入和输出
#define SDA_OUT PBout(7)//设置输出数据端口
#define SDA_IN PBin(7)//设置输入数据端口
//设置端口高8位的工作模式(具体可以参照端口位配置表),即I/O输入输出方向设置,先用与(&)对PB7引脚的四个位清0,再用或(|)置1
#define IIC_INPUT_MODE_SET()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=8<<28;}//改变PB7对应位为1000(CNF[1:0]MODE[1:0]),设置成上拉或者下拉输入
#define IIC_OUTPUT_MODE_SET() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=3<<28;}//改变PB7对应位为0011,设置成通用推挽输出
//#define IIC_INPUT_MODE_SET()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}//改变PB7对应位为1000(CNF[1:0]MODE[1:0]),设置成上拉或者下拉输入
//#define IIC_OUTPUT_MODE_SET() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=3<<12;}//改变PB7对应位为0011,设置成通用推挽输出//定义温湿度存储变量
u8 humiture_buff1[20];void SHT30_Init(void)//初始化SHT30的SCL与SDA接口
{GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(   RCC_APB2Periph_GPIOB, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;//定于SCL连接到STM32的PB6引脚上,定于SDA_OUT/SDA_IN连接到STM32的PB7引脚上GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);SCL=1;//根据SHT30时序要求,默认时序是高电平(SDA拉低时,SCL跟着拉低,开始数据的传输)SDA_OUT=1;//高电平还未开始数据的传输,拉低时开始数据的传输
}
//主机发送确认字符ACK
void IIC_ACK(void)//IIC协议,需要主机发送确认字符ACK来判断数据是否接收无误
{IIC_OUTPUT_MODE_SET();//配置PB7的SDA输出为推挽输出模式SCL=0;delay_us(2); SDA_OUT=0;delay_us(2);     SCL=1;//数据接收完成之后,将SCL拉高,以便与后面主机发送ACK给从机delay_us(2);                  SCL=0;//数据接收完成,主机发送ACK                     delay_us(1);
}
//主机不发送确认字符ACK
void IIC_NACK(void)//IIC协议,数据传输未完成或者数据传输有误,主机不发送确认字符ACK
{IIC_OUTPUT_MODE_SET();//配置PB7的SDA输出为推挽输出模式SCL=0;delay_us(2); SDA_OUT=1;delay_us(2);      SCL=1;delay_us(2);                   SCL=0;                     delay_us(1);
}
//主机等待从机的确认字符ACK
u8 IIC_wait_ACK(void)//主机等待从机发送ACK,从而判断数据是否接收完成
{u8 t = 200;IIC_OUTPUT_MODE_SET();SDA_OUT=1;//8位发送完后释放数据线,准备接收应答位 delay_us(1);SCL=0;delay_us(1); IIC_INPUT_MODE_SET();delay_us(1); while(SDA_IN)//等待SHT30应答{t--;delay_us(1); if(t==0){SCL=0;return 1;}delay_us(1); }delay_us(1);      SCL=1;delay_us(1);SCL=0;             delay_us(1);    return 0;
}
//启动IIC总线进行通讯,发送IIC通讯的起始条件
void IIC_Start(void)//启动IIC通讯
{IIC_OUTPUT_MODE_SET();//设置PB7的SDA为推挽输出SDA_OUT=1;//根据SHT30时序,启动之前,SDA配置为高电平SCL=1;根据SHT30时序,启动之前,SCL配置为高电平delay_us(4);//延时4us,给硬件一个反应时间SDA_OUT=0;//SDA引脚拉低,开始数据的传输delay_us(4);SCL=0;//SCL拉低,与SDA对应,响应SDA数据的拉低,表示正式开始数据的传输
}//结束IIC总线通讯,发送IIC通讯的结束条件
void IIC_Stop(void)
{IIC_OUTPUT_MODE_SET();SCL=0;//结束IIC通讯之前,查看SCL是否是拉低状态SDA_OUT=0;//结束IIC通讯之前,查看SDA是否是拉低状态  delay_us(4);   SCL=1;//将时钟拉高,表示已经结束IIC通讯delay_us(4);SDA_OUT=1;//将数据传输引脚拉高,表示正式结束数据的传输delay_us(4);
}//将byte数据发送出去
void  IIC_SendByte(u8 byte)
{u8  Count;IIC_OUTPUT_MODE_SET();SCL=0;//将时钟拉低,开始数据的传输for(Count=0;Count<8;Count++)//要传送的数据长度为8位{if(byte&0x80) SDA_OUT=1;//判断发送位,发送位为1,则还未发送数据else SDA_OUT=0; //判断发送位为0,则开始数据的发送byte<<=1;delay_us(2); SCL=1;delay_us(2);SCL=0;delay_us(2);}
}// 用来接收从器件传来的数据
u8 IIC_RcvByte(void)
{u8 retc;u8 Count;retc=0; IIC_INPUT_MODE_SET();//配置数据线为输入方式delay_us(1);                    for(Count=0;Count<8;Count++){  SCL=0;//配置时钟线为低,准备接收数据位delay_us(2);               SCL=1;//配置时钟线为高使数据线上数据有效                retc=retc<<1;if(SDA_IN) retc |=1;//读数据位,接收的数据位放入retc中 delay_us(1);}SCL=0;    return(retc);
}
//用来接收从器件采集并合成温湿度
void SHT30_read_result(u8 addr)
{//SHT30有两种读取数值的方法,分别是状态查询和数值查询,这里我使用的是数值查询,发送指令为0x2C06u16 tem,hum;//定义存放温湿度计算公式的变量u16 buff[6];//定义6个字节的数组,存放温度高、低八位,湿度高、低八位,两个字节的CRC校验位float Temperature=0;//定义存放温度拼接的变量Temperature,初始化温度为0float Humidity=0;//定义存放湿度拼接的变量Humidity,初始化湿度为0//发送指令为0x2C06(默认)IIC_Start();IIC_SendByte(addr<<1 | write);//写7位I2C设备地址加0作为写取位,1为写取位IIC_wait_ACK();
//  delay_us(1);IIC_SendByte(0x2C);//前半段发送指令为0x2CIIC_wait_ACK();
//  delay_us(1);IIC_SendByte(0x06);//后半段发送指令为0x06IIC_wait_ACK();
//  delay_us(1);IIC_Stop();delay_ms(50);IIC_Start();IIC_SendByte(addr<<1 | read);//写7位I2C设备地址加1作为读取位,1为读取位
//SHT30返回的数值是6个元素的数组if(IIC_wait_ACK()==0){//      delay_us(1);buff[0]=IIC_RcvByte();//返回温度高8位IIC_ACK();buff[1]=IIC_RcvByte();//返回温度低8位IIC_ACK();buff[2]=IIC_RcvByte();//温度crc校验位IIC_ACK();buff[3]=IIC_RcvByte();//返回湿度高8位IIC_ACK();buff[4]=IIC_RcvByte();//返回湿度低8位IIC_ACK();buff[5]=IIC_RcvByte();//湿度crc校验位IIC_NACK();IIC_Stop();}
//  tem = (buff[0]<<8) + buff[1];
//  hum = (buff[3]<<8) + buff[4];tem = ((buff[0]<<8) | buff[1]);//将buff[0]采集到的温度8位数据与buff[1]采集到的低8位数据相或,实现温度拼接hum = ((buff[3]<<8) | buff[4]);//将buff[3]采集到的湿度8位数据与buff[4]采集到的低8位数据相或,实现湿度拼接//查询SHT30数据手册可知,温湿度的计算方法如下    Temperature= 175.0*(float)tem/65535.0-45.0 ;// T = -45 + 175 * tem / (2^16-1)Humidity= 100.0*(float)hum/65535.0;// RH = hum*100 / (2^16-1)if((Temperature>=-20)&&(Temperature<=125)&&(Humidity>=0)&&(Humidity<=100))//设定温度和湿度的阈值,超过这个阈值则返回错误提示{printf("温度:%6.2f℃\r\n",Temperature);printf("湿度:%6.2f%%\r\n",Humidity);}else{printf("温湿度超过给定阈值!\r\n");}hum=0;tem=0;  }

2、sht30.h头文件

#ifndef _SHT30_H
#define _SHT30_H#include "delay.h"
#include "sys.h"
#include "stdio.h"
#include "usart.h"
#include "string.h"extern u8 humiture_buff1[20];void SHT30_Init(void);
void IIC_ACK(void);//确认字符,表示发来的数据已经确认接收无误
void IIC_NACK(void);//无确认字符,表示数据接收有误或者还未接收完成
u8 IIC_wait_ACK(void);//等待接收确认字符
void IIC_Start(void);//等待IIC传输数据开始
void IIC_Stop(void);//IIC传输数据停止
void IIC_SendByte(u8 byte);//IIC发送数据
u8 IIC_RcvByte(void);//IIC接收数据
void SHT30_read_result(u8 addr);//SHT30温湿度传感器开始读取数据#endif

3、main.c主函数

/*
本程序只供学习使用,未经作者许可,不得用于其他用途!
开 发 板:普中STM32-F1开发板
实验项目:基于STM32F103ZET6的SHT30温湿度检测实验
作    者:xxx//姓名暂时隐藏,有问题可以联系我下面邮箱
邮    箱:Zhangyc_Engineer@qq.com
日    期:2022年06月08日
版权所有,盗版必究。
*/
#include"stm32f10x.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "SHT30.h"int main(void){ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2delay_init();            //延时函数初始化   uart_init(9600);       //串口初始化为9600SHT30_Init();//初始化SHT30 printf("SHT30初始化正常,已准备就绪!\r\n");while(1){SHT30_read_result(0x44);//ADDR寄存器,地址选择引脚,接GND地址为0x44,接VDD地址为0x45delay_ms(1000);}
}

四、总结

1、时序图一定要去认真看懂,对应的源代码程序都是按照时序图一步一步去搭建的,如果自己私下里搭建的时候遇到错误,再返回来看看我的程序怎么去搭建的。
2、源代码中以下三个头文件的源代码我没有给大家贴出来:
#include “delay.h”
#include “sys.h”
#include “usart.h”
首先delay只是为了延时,然后sys只是系统配置,最后usart只是为了打印,所以这三个文件大家可以参考其他机构写的代码,例如正点原子
3、大家只有从底层去了解IIC,才能很好的掌握IIC,目前很多图形化界面,例如:STM32CubeMX就不需要手动去写IIC,直接在软件上配置即可。
4、温度和湿度转换公式已经贴在sht30.c文件里,大家也可以查看sht30官方推出的数据手册查看
5、文章开头IIC原理大家一定要认真看,每个字每个字认真看,我相信你看了会对IIC的认识更深一点

传感器:SHT30温湿度传感器检测环境温湿度实验(底部附代码)相关推荐

  1. VAE逻辑整理及VAE在异常检测中的小实验(附代码)

    VAE逻辑整理及VAE在异常检测中的小实验(附代码) Variance和control variate 两种常见的分类器 相应代码 Minst数据集的训练和重构 KDD99数据  本文主要讲解一下整个 ...

  2. 超声波测距仪编程_北邮小学期pic单片机-超声波测距仪实验报告(附代码).docx

    北邮小学期pic单片机-超声波测距仪实验报告(附代码) 2014年小学期单片机设计实验报告 题目:超声波测距仪 目录 TOC \o "1-3" \h \z \u HYPERLINK ...

  3. YOLOV5 的小目标检测网络结构优化方法汇总(附代码)

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨南山 来源丨 AI约读社 YOLOv5是一种非常受欢迎的单阶段目标检测,以其性能和速度著称,其结 ...

  4. 如何构建一个生产环境的推荐系统?(附代码)

    导读:现在互联网上的内容很多,我们可能每天都会接受来自不同消息.例如,电商网站.阅读博客.各类新闻文章等.但是,这些消息并不是所有的内容你都感兴趣,可能你只对技术博客感兴趣,或者某些新闻感兴趣等等.而 ...

  5. GhostNet 解读及代码实验(附代码、超参、日志和预训练模型)

    文章首发于 极市平台 文章目录 一.前言 二.论文阅读 摘要 问题1: 何为特征图冗余? 问题2: Ghost feature maps 和 Intrinsic feature maps 是什么? 问 ...

  6. 如何在UBUNTU虚拟机上编译EOS完成环境搭建?(附代码)

    1 摘要 [本文目标] 通过本文实践,能在WINDOWS操作系统搭建UBUNTU 18.04 LTS环境,并在此环境编译成功EOS v1.0.5正式发布版本. [前置条件] 有学习EOS环境搭建意向, ...

  7. 温湿度传感器——DHT11学习总结

    一.DHT11的简单介绍 DHT11是一款有已校准数字信号输出的温湿度传感器. 其精度湿度±5%RH, 温度±2℃, 量程湿度20-90%RH, 温度0~50℃--百度百科 注解:相对湿度(RH)是指 ...

  8. [单片机芯片]CH32V307驱动单总线温湿度传感器DHT22

    手头有一个DHT22温湿度传感器和CH32V307开发板,可玩性极强.DHT22是已校准的数字温湿度传感器,用于检测环境温湿度,采用DHT22(AM2302),标准单总线接口.拥有比常见的DHT11更 ...

  9. STM32CubeMX系列|DHT11温湿度传感器

    DHT11温湿度传感器 1. DHT11简介 DHT11是一款温湿度一体化的数字传感器,该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机连接.通过单片机微处理器简单的电路连 ...

最新文章

  1. VS2019 无法解析的外部符号 cublasSgemm_v2
  2. MySQL编译安装及主从配置
  3. 解决navicat 导出excel数字为科学计数法问题
  4. linux kernel同步方法的总结
  5. ftp shell lcd不起作用
  6. SAP Cloud SDK for JavaScript 的搭建和使用方法介绍
  7. Python安装pyinstaller模块的错误:NO module name “setuptools“
  8. SOAP协议初级指南(9)
  9. 编程语言python怎么读-Python入门学习的计算机程序设计语言是怎样的?
  10. json中保存数据与解析数据与python中json模块做对应关系
  11. 【mcuclub】红外测温-MLX90614
  12. Android 11.0 MTK去掉开机通过长按电源键+音量加进入recovery 工厂模式
  13. 【区块链扩容】侧链技术 Plasma(Layer 2)
  14. HowTo——cotex-m3处理器HardFault事后分析方法
  15. 计算机二级msoffice必做题型,计算机二级MS Office考试 题型汇总附答案
  16. NX 查看NX图标名
  17. 微信小程序开发—入门到跑路(一)
  18. 配置失败还原请勿关闭计算机,win7系统遇到更新失败提示“配置windwos update 失败还原更改,请勿关闭计算机”的解决方法...
  19. Excel:VBA数据分析-找到含某个关键字的单元格就标黄(五)
  20. bzoj4808: 马(最小割)

热门文章

  1. 项目开发——【流程图】软件工程程序流程图详解《如何正确绘制项目开发流程图》
  2. 地理空间数据库复习笔记:概论、关系模型与关系代数
  3. catia草图线束--不然固定不了---约束后变为绿色
  4. 关于 batis.binding.BindingException: Invalid bound statement (not found) 解决方案
  5. 我的阿里Offer之路(一):不忘初心,重拾Java
  6. figma设计用户头像效果
  7. 如何将多张CAD图纸转换成彩色清晰的WMF格式?
  8. python行业中性_【建投金工丁鲁明团队 经典回顾】:零基础python代码策略模型实战...
  9. Azure 设计模式之大使模式
  10. SQL Server 数据库附加操作时,附加的的数据库只读的解决