STM32F103ZET6+IIC+SHT20温湿度传感

IIC概述

IIC:两线式串行总线,它是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。

在CPU与被控IIC之间、IIC与IIC之间进行双向传送,高速IIC总线一般可达400kbs以上。总线上可以接多个从设备,从设备的地址必须不同。也可也接多个主设备,但同一时刻只能有一个主设备控制总线。最大设备数量受总线的最大负载电容400pf限制。每个从设备有自己的设备地址,主设备发送START信号后,紧跟着发送想要通信的从设备地址字节,7位器件地址+1位读写标志位(0为写,1为读)。

时钟线SCL:在通信过程起到控制作用。
数据线SDA:用来一位一位的传送数据。

IIC总共由五个核心函数,分别为:①起始信号②停止信号③应答信号④发送数据⑤接收数据,通过这五个核心基本函数就能于大多数的传感进行通信了。

起始信号
当SCL为高电平期间,SDA由高电平到低电平的跳变过程;起始信号是一种电平跳变时序信号,而不是一个电平信号,如图虚线框所示。

停止信号
当SCL为高电平期间,SDA由低电平到高电平的跳变过程;停止信号也是一种电平跳变时序信号,而不是一个电平信号,如图虚线框所示。

应答信号
IIC的数据字节定义为8位长,对于发送端每发送1个字节后,需要将数据线(SDA)释放,由接收端反馈一个应答信号(ACK)。应答信号为低电平时,则将其规定为有效信号(ACK简称应答位),表示接收端已经成功接收了该字节;应答位为高电平时,规定为非应答位(NACK),一般表示接收端没有成功接收该字节。
对于反馈有效应答位ACK的要求是,接收端在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。如果接收端是主机,则在它接收到最后一个字节后,发送一个NACK信号,以通知发送端结束数据发送,并释放SDA线,以便主机接收端发送一个停止信号。

发送数据
在发送起始信号后开始通信,主机发送一个8位数据。然后,主机释放SDA线并等待从从机发出得确认信号(ACK)。

接收数据
在发送起始信号后开始通信,主机发送一个8位数据。然后,从机收到数据返回一个确认信号(ACK)给主机,这时候主机才开始接收数据,待主机接收数据完成后,发送一个NACK信号给从机,以通知接收端结束数据接收。

数据有效性
IIC总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。

IIC通信总过程

大概地了解了一下,IIC协议的基本情况,接下来,使用STM32驱动SHT20温湿度传感器为例,熟悉一下IIC协议的应用。

准备IIC协议
1、声明GPIO和IIC初始化

void SHT20_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(SHT20_SCL_GPIO_CLK | SHT20_SDA_GPIO_SDA, ENABLE);GPIO_InitStructure.GPIO_Pin = SHT20_SCL_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SHT20_SCL_GPIO_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = SHT20_SDA_GPIO_PIN;GPIO_Init(SHT20_SDA_GPIO_PORT, &GPIO_InitStructure);
}

2、IIC数据线的输出模式
因为在IIC数据线输出数据前,需要将数据线设置为输出模式才行

void SDA_OUT(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SHT20_SDA_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SHT20_SDA_GPIO_PORT, &GPIO_InitStructure);
}

3、IIC数据线的输入模式
同样在IIC数据线输入数据前,需要将数据线设置为输入模式才行

void SDA_IN(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SHT20_SDA_GPIO_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(SHT20_SDA_GPIO_PORT, &GPIO_InitStructure);
}

4、IIC起始信号

void IIC_Start(void)
{SDA_OUT();SHT20_SDA = 1;SHT20_SCL = 1;delay_us(20);SHT20_SDA = 0;delay_us(20);SHT20_SCL = 0;
}

5、IIC停止信号

void IIC_Stop(void)
{SDA_OUT();SHT20_SCL = 0;SHT20_SDA = 0;delay_us(20);SHT20_SCL = 1;SHT20_SDA = 1;delay_us(20);
}

6、IIC等待应答信号
返回值:1,接收应答失败;0,接收应答成功。

u8 IIC_Wait_Ack(void)
{u8 ucErrTime = 0;SDA_IN();SHT20_SDA = 1;delay_us(10);SHT20_SCL = 1;delay_us(10);while(SHT20_SDA_READ()){ucErrTime++;if(ucErrTime > 250){IIC_Stop();return 1;}}SHT20_SCL = 0;  return 0;
}

7、IIC产生应答信号

void IIC_Ack(void)
{SHT20_SCL = 0;SDA_OUT();SHT20_SDA = 0;delay_us(20);SHT20_SCL = 1;delay_us(20);SHT20_SCL = 0;
}

8、IIC不产生应答信号

void IIC_NAck(void)
{SHT20_SCL = 0;SDA_OUT();SHT20_SDA = 1;delay_us(20);SHT20_SCL = 1;delay_us(20);SHT20_SCL = 0;
}

9、IIC发送一个字节
返回从机有无应答,1,有应答;0,无应答。

void IIC_Send_Byte(u8 txd)
{u8 t;SDA_OUT();SHT20_SCL = 0;     for(t = 0; t < 8; t++){if((txd & 0x80) >> 7)SHT20_SDA = 1;elseSHT20_SDA = 0;txd <<= 1;delay_us(20);SHT20_SCL = 1;delay_us(20);SHT20_SCL = 0;delay_us(20);}delay_us(20);}

10、IIC读取一个字节
读取字节时,ask=1,产生应答;ask=0,不产生应答

u16 IIC_Read_Byte(u8 ack)
{u8 i;u16 receive = 0;SDA_IN();for(i = 0; i < 8; i++ ){SHT20_SCL = 0;delay_us(20);SHT20_SCL = 1;receive <<= 1;if(SHT20_SDA_READ())receive++;delay_us(20);}if (!ack)IIC_NAck();elseIIC_Ack(); return receive;
}

温湿度传感器的驱动过程

STH20数据手册下载链接

有两种不同的操作模式与传感器通信:保持主模式或无保持主模式。在第一种情况下,SCL 线路在测量过程中阻塞(由传感器控制),而在后一种情况下,在传感器处理测量时,SCL线路保持打开状态,以进行其他通信。在传感器测量时,无保持主2模式允许处理总线上的其他 I 2 C 通信任务。

在保持主模式下,SHT20 在测量时拉下 SCL 线以等待状态。通过释放 SCL 线路 ,传感器指示内部处理已终止,并且传输可能继续。


在无保持主模式下,MCU 必须轮询,以终止 Sensor 的内部处理。这是通过发送开始条件后跟 II C 标头完成的,如果内部处理完成,传感器将确认 MCU 的轮询,MCU 可以读取数据。如果测量处理未完成,传感器应答无 ACK 位,并且必须再次发出"启动"条件。使用无保持主模式 mode时,建议在接收传感器的 ACK 位后包括 20 μs的等待时间,并处于"停止"状态之前。


驱动代码如下:

float ReadSht20(unsigned char whatdo)
{float temp;unsigned char MSB,LSB;float Humidity,Temperature;IIC_Start();IIC_Send_Byte(0x80);if(IIC_Wait_Ack()==0){IIC_Send_Byte(whatdo);if(IIC_Wait_Ack()==0){do{delay_us(8);IIC_Start();  IIC_Send_Byte(0x81);}while(IIC_Wait_Ack()==1);MSB = IIC_Read_Byte(1);LSB = IIC_Read_Byte(1);IIC_Read_Byte(0); IIC_Stop();LSB &= 0xfc;temp = MSB*256 + LSB;if (whatdo==((unsigned char)0xf5)){        Humidity =(temp*125)/65536-6;return Humidity;}                                                                                                  else      {        Temperature = (temp*175.72)/65536-46.85;return Temperature; }}}return 0;
}

在之前的USART工程上,新建两个文件,一个是SHT20.h文件,另一个是SHT20.c文件

SHT20.h文件的代码如下:

#ifndef __HX711_H
#define __HX711_H#include "sys.h"
#include "delay.h"#define  SHT20_SCL   PEout(11)
#define  SHT20_SDA   PEout(12)// GPIO 引脚定义
#define  SHT20_SCL_GPIO_CLK        RCC_APB2Periph_GPIOE
#define  SHT20_SCL_GPIO_PORT       GPIOE
#define  SHT20_SCL_GPIO_PIN        GPIO_Pin_11#define  SHT20_SDA_GPIO_SDA        RCC_APB2Periph_GPIOE
#define  SHT20_SDA_GPIO_PORT       GPIOE
#define  SHT20_SDA_GPIO_PIN        GPIO_Pin_12#define  SHT20_SDA_READ()          GPIO_ReadInputDataBit(SHT20_SDA_GPIO_PORT, SHT20_SDA_GPIO_PIN)//IIC 所有操作函数
void SHT20_GPIO_Init(void);void SDA_OUT(void);
void SDA_IN(void);
void IIC_Start(void);
void IIC_Stop(void);
u8 IIC_Wait_Ack(void);
void IIC_Ack(void);
void IIC_NAck(void);
void IIC_Send_Byte(u8 txd);
u16 IIC_Read_Byte(u8 ack);float ReadSht20(unsigned char whatdo);#endif

SHT20.c文件的代码如下:

#include "SHT20.h"void SHT20_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(SHT20_SCL_GPIO_CLK | SHT20_SDA_GPIO_SDA, ENABLE);GPIO_InitStructure.GPIO_Pin = SHT20_SCL_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SHT20_SCL_GPIO_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = SHT20_SDA_GPIO_PIN;GPIO_Init(SHT20_SDA_GPIO_PORT, &GPIO_InitStructure);
}void SDA_OUT(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SHT20_SDA_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SHT20_SDA_GPIO_PORT, &GPIO_InitStructure);
}void SDA_IN(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SHT20_SDA_GPIO_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(SHT20_SDA_GPIO_PORT, &GPIO_InitStructure);
}void IIC_Start(void)
{SDA_OUT();SHT20_SDA = 1;SHT20_SCL = 1;delay_us(20);SHT20_SDA = 0;delay_us(20);SHT20_SCL = 0;
}void IIC_Stop(void)
{SDA_OUT();SHT20_SCL = 0;SHT20_SDA = 0;delay_us(20);SHT20_SCL = 1;SHT20_SDA = 1;delay_us(20);
}u8 IIC_Wait_Ack(void)
{u8 ucErrTime = 0;SDA_IN();SHT20_SDA = 1;delay_us(10);SHT20_SCL = 1;delay_us(10);while(SHT20_SDA_READ()){ucErrTime++;if(ucErrTime > 250){IIC_Stop();return 1;}}SHT20_SCL = 0;  return 0;
}void IIC_Ack(void)
{SHT20_SCL = 0;SDA_OUT();SHT20_SDA = 0;delay_us(20);SHT20_SCL = 1;delay_us(20);SHT20_SCL = 0;
}void IIC_NAck(void)
{SHT20_SCL = 0;SDA_OUT();SHT20_SDA = 1;delay_us(20);SHT20_SCL = 1;delay_us(20);SHT20_SCL = 0;
}void IIC_Send_Byte(u8 txd)
{u8 t;SDA_OUT();SHT20_SCL = 0;     for(t = 0; t < 8; t++){if((txd & 0x80) >> 7)SHT20_SDA = 1;elseSHT20_SDA = 0;txd <<= 1;delay_us(20);SHT20_SCL = 1;delay_us(20);SHT20_SCL = 0;delay_us(20);}delay_us(20);}u16 IIC_Read_Byte(u8 ack)
{u8 i;u16 receive = 0;SDA_IN();for(i = 0; i < 8; i++ ){SHT20_SCL = 0;delay_us(20);SHT20_SCL = 1;receive <<= 1;if(SHT20_SDA_READ())receive++;delay_us(20);}if (!ack)IIC_NAck();elseIIC_Ack();return receive;
}float ReadSht20(unsigned char whatdo)
{float temp;unsigned char MSB,LSB;float Humidity,Temperature;IIC_Start();IIC_Send_Byte(0x80);if(IIC_Wait_Ack()==0){IIC_Send_Byte(whatdo);if(IIC_Wait_Ack()==0){do{delay_us(8);IIC_Start();  IIC_Send_Byte(0x81);}while(IIC_Wait_Ack()==1);MSB = IIC_Read_Byte(1);LSB = IIC_Read_Byte(1);IIC_Read_Byte(0); IIC_Stop();LSB &= 0xfc;temp = MSB*256 + LSB;if (whatdo==((unsigned char)0xf5)){        Humidity =(temp*125)/65536-6;return Humidity;}                                                                                                  else      {        Temperature = (temp*175.72)/65536-46.85;return Temperature; }}}return 0;
}

main.c文件的代码如下:

#include "stm32f10x.h"
#include <stdio.h>
#include "led.h"
#include "USART_Init_Config.h"
#include "SHT20.h"int main(void)
{float Humidity,Temperature;   //定义温度和湿度变量delay_init();      //延时函数初始化LED_Init();          //LED灯初始化USART_Init_Config(); //串口初始化SHT20_GPIO_Init();   //SHT20初始化while(1){Humidity = ReadSht20(0xf3);           //读取温度printf("温度为:%0.2f",Humidity);Temperature = ReadSht20(0xf5);     //读取湿度printf("湿度为:%0.2f",Temperature);delay_ms(1000);}}

运行效果

打开串口调试助手

完整工程下载!!!

STM32F103ZET6+IIC+SHT20温湿度传感相关推荐

  1. STM32F103ZET6+IIC+BH1750光照强度传感

    STM32F103ZET6+IIC+BH1750光照强度传感 为了加深对IIC协议的理解和应用,接下来,使用STM32驱动BH1750光照强度传感器 准备IIC协议 其实IIC协议还是之前的驱动温湿度 ...

  2. 基于STM32F1单片机、ESP8266WIFI模块、DHT11温湿度传感的WIFI网络温湿度传输系统

    基于STM32F1单片机.ESP8266WIFI模块.DHT11温湿度传感的WIFI网络温湿度传输系统 功能说明 温湿度采集端 温湿度监控端 硬件材料 硬件连接 主要代码 温湿度采集端 温湿度监控端 ...

  3. sht20温湿度传感器原理图_温湿度传感器在孵化行业怎么应用

    随着近年来环保力度的加大,畜牧养殖行业逐渐认识到节能减排.环境控制对于畜禽养殖具有重要意义,并且节能环保控制已开始出现在孵化行业. 以前,一些家禽孵化场没有恒温恒湿的概念,他们认为孵化是一个带有孵化设 ...

  4. STM32F405 标准库 SHT20温湿度传感器

    SHT20是个温湿度传感器,使用I2C通信 下面的I2C程序需要换成你们自己的I2C程序 SoftReset函数:硬件初始化 SET_Resolution函数:设置分辨率 ReadSht20函数:开始 ...

  5. android温湿度传感节点指令源代码,Arduino+DHT11+OLED显示温湿度信息(附详细文档+源码)...

    设计者:STCode (公众号同名) 第一章 绪论 1.1实训设计背景与意义 随着生活水平的提高和科技水平的发展,人们对自身和家庭安全方面的考虑也越来越多,越来越多的安全监测系统和设备进入到人们的生活 ...

  6. 【毕设项目】基于STM32F103ZET6的土壤温湿度数据采集和存储系统

    目录导航 一.前言 二.准备工作 三.实现流程 1.keil编程 2.机智云台开发 3.Android开发 四.数据可视化分析 五.小结 一.前言 上一篇博客提到<正点原子STM32f103ZE ...

  7. STM32_光敏、温湿度传感的选择?

    光敏 检测阳光,有三种方案. 第一种,是使用红外接收管.太阳光中占大部分的是红外线光,红外接收管的结构是特殊材质的PN结二极管,红外接收管的阻值会随着照射到其接收点上的太阳光强度的增大而减小,其精确度 ...

  8. 基于STM32开发板实现温湿度传感数据采集

    一.实验要求 本实验将选用STM32F407ZGT6开发板进行项目开发,选用的传感器为DHT11温湿度传感器.传感器将采集到的数据传输到STM32(MCU)主控进行数据处理,最后通过串口打印出来. 二 ...

  9. STM32使用IIC总线通讯协议在OLED屏幕上显示字符串、汉字、单总线获取DHT11模块温湿度并通过IIC显示到屏幕(软件IIC)

    参考:基于stm32软件IIC的oled显示温湿度 作者:ZPZ DayUp 发布时间: 2021-07-25 20:52:43 网址:https://blog.csdn.net/m0_5619768 ...

  10. 血氧心率测量仪(带温湿度测量功能)OLED显示

    血氧心率测量仪(带温湿度测量功能)OLED显示 原理图资料 模块说明 测试数据处理图 部分代码展示 资料包 原理图资料 模块说明 数字温湿度传感 DHT11 ►相对湿度和温度测量 ►全部校准,数字输出 ...

最新文章

  1. 微信按钮android代码实现原理,微信小程序button标签open-type实现原理
  2. 《死亡细胞》中神秘背景世界色彩设计(上)
  3. oracle安装出现getproces,oracle安装问题
  4. Beyond Compare配置
  5. ubuntu17.04之apt-get源
  6. dataframe数据标准化处理_数据处理中的标准化、归一化究竟是什么?
  7. tensorflow with gpu 环境配置
  8. AI赋能新闻播报 搜狐新闻客户端联合搜狗打造首个明星“数字人”主播
  9. 深度linux添加xp,Linux和Windos XP下向路由表添加路由
  10. vue(组件、路由)懒加载
  11. errors collectiions
  12. python图书管理实训报告总结_图书管理系统实训报告正文
  13. 自然语言处理(NLP)
  14. 配置环境变量时Path单行显示问题
  15. word打字时后面的字会消失是什么原因?如何解决?
  16. PS怎么制作下雨天玻璃水雾图片效果
  17. Java破解9X9数独小游戏
  18. 成人c语言培训,C语言程序设计在成人教育中教学.doc
  19. JAVA之bootstrap01
  20. 二叉树输出(凹入表示法)

热门文章

  1. 日骗上百的淘宝网赚项目骗局
  2. 软路由ros(MIKROTIK)安装教程:[11]端口映射
  3. stm32+rx8025
  4. make px4_sitl gazebo报错:FAILED: ROMFS/romfs_extract.stamp
  5. 高清视频格式-BD-remux、BD-RE、BDRip的区别
  6. hd计算机技术,BD和HD的区别是什么?
  7. 公司办公用品管理软件(AssetManage 2011) v11.0.3破解版
  8. Astah Professional三维图,网络上轻松上传图表
  9. 安捷伦电源6319D实现GPIB通信
  10. 总线及单片机各种线 以及数据总线宽度