STM32之模拟IIC总线控制SHT20温湿度芯片

一、IIC总线概述

1、IIC总线介绍

I2C (Inter-Integrated Circuit)总线产生于在80年代, 由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备, 最初为音频和视频设备开发。I2C总线两线制包括:串行数据SDA(Serial Data)、串行时钟SCL(Serial Clock)。时钟线必须由主机(通常为微控制器)控制,主机产生串行时钟(SCL)控制总线的传输方向,并产生起始和停止条件。I2C总线上有主机(MCU)和从机(片外外设,如AT24C02)之分,可以有多个主机和多个从机。从机永远不会主动给主机发送数据。器件发送数据到总线上,则定义为发送器,器件接收数据则定义为接收器。主器件和从器件都可以工作于接收和发送状态。

USART : 异步串行全双工

SPI: 同步串行全双工

IIC:同步串行半双工

挂载在同一根IIC总线上可以有多个设备,有主机和从机之分

2、IIC总线物理拓扑图

3、IIC总线主从设备通信

SPI如何解决从多个从机中选择一个通信:片选线

IIC如何解决从多个从机中选择一个通信: 器件地址

首先向外界发出一个器件地址

所有挂载在这个总线上的设备都可以接收到这个地址

设备获取到这个器件地址后和本身的地址作比较

匹配的设备就会接下来接收主机发出的数据

其他设备重新处于休眠状态

器件地址:一般是7位的硬件地址 + 1位的读写位

IIC通信规定一次发送的数据是8位的

针对主机而言:

写(向外界发送数据):0

读(从外界接收数据):1

4、IIC总线与UART比较

通讯协议UARTIICSPI
特征异步串行全双工同步串行半双工同步串行全双工
接口TX、RXSDA、SCLMOSI、MISO、CS、SCK
速度波特率很多100Khz、400Khz、3.5MhzMhz级以上
数据帧格式起始位+数据位+校验位+停止位起始条件+位传输+应答+停止条件四种MODE0-3
主从设备通讯没有主从之分有主从之分有主从之分
总线结构一对一一对多一对多
发送数据顺序先发低位再发高位先发高位再发低位

先发高位再发低位

SPI控制器可以选择先低后高还是先高后低

二、IIC总线数据

1、IIC数据帧的格式

起始条件(告诉接收方要开始发送数据了):在时钟线高电平期间,数据线产生下降沿

数据的传输:时钟线低电平期间发送数据,高电平期间接收数据,需要给一定的时间让数据可以发送和接收

高位先发,8位数据的发送

应答位:1个位的数据,代表当前有没有受到数据,是接收方回发给发送方的

(0)应答:代表接收到数据并且可以继续发送

(1)非应答:代表当前不能再接受数据了

停止条件(代表一次通信结束):在时钟线高电平期间,数据线产生上升沿

2、标准IIC时序(100khz)

1、起始条件
SDA = 1;
SCL = 1;
Delay_us(4);//起始条件的建立时间
SDA = 0;
Delay_us(4);//起始条件的保持时间
SCL = 0;//一个完整的时钟周期

2、停止条件
SDA = 0;
SCL = 1;
Delay_us(4);//停止条件的建立时间
SDA = 1;
Delay_us(4);//停止和启动条件之间的总线空闲时间

3、位传输
高位先发,高电平期间接收数据,低电平期间发送数据

主机发送数据(发送的是写方向):
for( i = 0 ; i < 8; i++)
{
        SCL = 0;
        SDA = 0/1;
        Delay_us(4);//主机发送数据的时间
        SCL = 1;
        Delay_us(4);//从机接收数据的时间
}

主机接收数据:(发送的是读方向)
for( i = 0 ; i < 8; i++)
{
        SCL = 0;
        Delay_us(4);//从机发送数据的时间
        SCL = 1;
        if(SDA)
        {
                Data |= 1;
        }
        Delay_us(4);//主机接受数据的时间
}

4、应答

主机发送一个应答位:
    SCL = 0;
    SDA = 0/1;
    Delay_us(4);//主机发送数据的时间
    SCL = 1;
    Delay_us(4);//从机接收数据的时间
    SCL = 0;
    Delay_us(4);//保证周期的完整性


主机接收一个应答位:
    SCL = 0;
    Delay_us(4);//从机发送数据的时间
    SCL = 1;
    if(SDA)
    {
        Data = 1;
    }
    Delay_us(4);//主机接受数据的时间
    SCL = 0;
    Delay_us(4);//保证周期的完整性
 

三、SHT20温湿度芯片

1、硬件:

相对湿度的误差在±3

湿度范围:0 - 100%

温度的误差在±0.3摄氏度

温度范围:-40 - 125摄氏度

管脚说明:

SCL: IIC通信的时钟线

SDA: IIC通信的数据线

SHT20采用IIC的400kHZ的通信速率

测量温度的命令:0xf3

测量湿度的命令:0xf5

器件地址 + 写方向:0x80

器件地址 + 写方向:0x81

2、软件:

通信步骤:
1. 传感器上电,最多等待15ms的时间再去发送相应的命令
2. 发送器件地址 + 方向位以及相应的命令去触发测量

3、时序

起始条件--->发送器件地址 + 写方向(0x80) --> 如果通信正常则回应答位 --> 发送测量温湿度数据的命令-->

起始条件--->不断发送发送器件地址 + 读方向(0x81)直到回了一个应答才停止发送器件地址 + 读方向(0x81)-->如果回了应答就可以接收从机发过来的数据(16位构成的),需要接收两次才完整,先发送过来的数据是16位数据中的高八位----->接受完16位的数据主机发送非应答告诉SHT20不用再回发数据---->停止条件

注意:接收回来的16位数据中最低两位要清零

起始条件 ---->发送器件地址 + 写方向(0x80)---->等待sht20应答 ---->发送软复位指令(0xfe)等待sht20应答 ---->停止条件

写用户寄存器:

起始条件 ---->发送器件地址 + 写方向(0x80)---->等待sht20应答 ---->发送0xe6告诉SHT20要往用户寄存器里写值----> 等待sht20应答 ---->发送需要写到里面的值---->等待sht20应答 ----->停止条件

RH  = -6 + 125 * Srh / 65536

T = -46.85 + 175.72 * St / 65536

初始化GPIO口

PB8 -- SCL -- 推挽输出

PB9 -- SDA

输入输出模式切换

SDA线既可以接收数据也可以发送数据

输入模式的时候不能输出数据

输出模式的时候可以读取数据

开漏输出

开漏输出:只能输出低电平

如果输出高电平就是断开输出电路

#include "iic.h"
/****************************
函数功能:初始化IIC总线的IO口
函数形参:void
函数返回值:void
函数说明:
PB8 -- SCL -- 推挽输出
PB9 -- SDA 
1.输入输出模式切换
SDA线既可以接收数据也可以发送数据
输入模式的时候不能输出数据
输出模式的时候可以读取数据
2.开漏输出
开漏输出:只能输出低电平
如果输出高电平就是断开输出电路
****************************/
void Iic_PortInit(void)
{GPIO_InitTypeDef  GPIO_InitStruct;//定义了一个结构体变量//1. 打开GPIOB的时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//2. 配置GPIO口功能GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;//配置输出模式GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//配置为推挽GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;//选择8号管脚GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉GPIO_InitStruct.GPIO_Speed = GPIO_Low_Speed;//低速GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;//配置为开漏GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;//选择9号管脚GPIO_Init(GPIOB, &GPIO_InitStruct); }/****************************
函数功能:起始条件
函数形参:void
函数返回值:void
函数说明:在时钟线高电平期间,数据线产生下降沿
****************************/
void IIC_Start(void)
{SDA_H;SCL_H;Delay_Us(4);//起始条件的建立时间SDA_L; Delay_Us(4);//起始条件的保持时间SCL_L;//保证周期完整
}/****************************
函数功能:停止条件
函数形参:void
函数返回值:void
函数说明:在时钟线高电平期间,数据线产生上升沿
****************************/
void IIC_Stop(void)
{SDA_L;SCL_H;Delay_Us(4);//停止条件的建立时间SDA_H;Delay_Us(4);//停止和启动条件之间的总线空闲时间
}/****************************
函数功能:发送应答位
函数形参:u8 ack
函数返回值:void
函数说明:0:代表应答1:代表非应答
****************************/
void Send_Ack(u8 ack)
{SCL_L;//发送方准备发送数据if(ack){SDA_H;}else{SDA_L;}Delay_Us(4);//发送数据所需要的时间SCL_H;Delay_Us(4);//接收数据所需要的时间SCL_L;Delay_Us(4);//保证一个完整的周期}/****************************
函数功能:接收应答位
函数形参:void
函数返回值:u8
函数说明:0:代表应答1:代表非应答
****************************/
u8 Receive_Ack(void)
{u8 ack = 0;SDA_H;//断开输出电路SCL_L;//发送方准备发送数据Delay_Us(4);//发送数据所需要的时间SCL_H;if(SDA){ack = 1;}Delay_Us(4);//接收数据所需要的时间SCL_L;Delay_Us(4);//保证一个完整的周期return ack;
}/****************************
函数功能:发送一个字节并接收一个应答位
函数形参:u8 data
函数返回值:u8
函数说明:0:代表应答1:代表非应答
****************************/
u8 Send_Byte_Receive_Ack(u8 data)
{u8 i,ack = 0;for(i = 0; i < 8; i++){SCL_L;//发送方准备发送数据//1100 0011//0100 0000if(data & 0x80 >> i){SDA_H;}elseSDA_L;Delay_Us(4);//发送数据所需要的时间SCL_H;Delay_Us(4);//接收数据所需要的时间}ack = Receive_Ack();return ack;
}/****************************
函数功能:接收一个字节并发送一个应答位
函数形参:u8 data
函数返回值:u8
函数说明:0:代表应答1:代表非应答
****************************/
u8 Receive_Byte_Send_Ack(u8 ack)
{u8 i = 0;u8 data = 0;for(i = 0; i < 8; i++){SCL_L;//发送方准备发送数据Delay_Us(4);//发送数据所需要的时间SDA_H;//断开输出电路SCL_H;data <<= 1;//空出最低位if(SDA){data |= 1;}Delay_Us(4);//接收数据所需要的时间}Send_Ack(ack);return data;
}
#ifndef __IIC_H_
#define __IIC_H_#include "stm32f4xx.h"
#include "delay.h"#define SCL_H  GPIO_SetBits(GPIOB,GPIO_Pin_8)
#define SCL_L  GPIO_ResetBits(GPIOB,GPIO_Pin_8)
#define SDA_H  GPIO_SetBits(GPIOB,GPIO_Pin_9)
#define SDA_L  GPIO_ResetBits(GPIOB,GPIO_Pin_9)
#define SDA    GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)void Iic_PortInit(void);
void IIC_Start(void);
void IIC_Stop(void);
u8 Send_Byte_Receive_Ack(u8 data);
u8 Receive_Byte_Send_Ack(u8 ack);#endif

完整版代码例程在

【免费】STM32控制SHT20温湿度芯片资源-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/232683.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rustdesk打开Win10 下客户端下面服务不会自启,显示服务未运行

环境: Rustdesk1.19 问题描述: Rustdesk打开Win10 下客户端下面服务不会自启,显示服务未运行 解决方案: 1.查看源代码 pub async fn start_all() {crate::hbbs_http::sync::start();let mut nat_tested = false;check_zombie()

银行十大主题域

当事人、产品、协议、事件、资产、财务、机构、地域、营销、渠道 便于记忆&#xff1a; 银行是一个企业&#xff0c;同时也是一个机构&#xff0c;涉及企业机构就会有资产&#xff0c;财务的存在&#xff0c;银行有自己的产品&#xff08;信用卡&#xff0c;黄金&#xff0c;期…

【小沐学CAD】开源Assimp库导入三维模型(C++、Python)

文章目录 1、简介2、下载编译3、代码测试3.1 C3.2 pyassimp&#xff08;Python&#xff09; 结语 1、简介 https://github.com/assimp/assimp Open Asset Import Library 是一个库&#xff0c;用于将各种 3D 文件格式加载为共享的内存格式。它支持 40 多种用于导入的文件格式和…

PDF.js实现搜索多个不同的关键词高亮显示效果

static\PDF\web\viewer.js 392行左右 // 自定义搜索关键词---------------------------------------- this.searchKeywords = keyword => {if (typeof PDFViewerApplication !== undefined) {PDFViewerApplication.eventBus.dispatch(find, {query: keyword,caseSensitive:…

AQS 抽象队列同步器

AQS AQS &#xff08;抽象队列同步器&#xff09;&#xff1a; AbstractQueuedSynchronizer 是什么 来自jdk1.5&#xff0c;是用来实现锁或者其他同步器组件的公共基础部分的抽象实现&#xff0c;是重量级基础框架以及JUC的基石&#xff0c;主要用于解决锁分配给谁的问题整体…

互联网演进历程:从“全球等待”到“全球智慧”的技术革新与商业变革

文章目录 一、导言二、World Wide Wait (全球等待)阶段1. 技术角度2. 用户体验3. 企业收益4. 教育影响 三、World Wide Web (万维网)阶段1. 技术角度2. 用户体验3. 企业收益4. 教育影响 四、World Wide Wisdom (全球智慧)阶段1. 技术角度2. 用户体验3. 企业收益4. 教育影响 五、…

MySQL——用户管理

目录 一.用户管理 二.用户 1.用户信息 2.创建用户 3.删除用户 4. 修改用户密码 三.数据库的权限 1.给用户授权 2.回收权限 一.用户管理 如果我们只能使用root用户&#xff0c;root的权限非常大,这样存在安全隐患。这时&#xff0c;就需要使用MySQL的用户管理&#xff…

苦学golang半年,写了一款web服务器

苦学golang半年&#xff0c;写了一款web服务器 文章目录 苦学golang半年&#xff0c;写了一款web服务器example 项目地址&#xff1a;https://github.com/fengyuan-liang/jet-web-fasthttp 可以的话&#xff0c;请star支持一下&#x1f642; 苦学golang半年&#xff0c;写了一款…

java基于vue的音乐播放器的设计与实现论文

摘 要 当下&#xff0c;如果还依然使用纸质文档来记录并且管理相关信息&#xff0c;可能会出现很多问题&#xff0c;比如原始文件的丢失&#xff0c;因为采用纸质文档&#xff0c;很容易受潮或者怕火&#xff0c;不容易备份&#xff0c;需要花费大量的人员和资金来管理用纸质文…

【Spring Cloud】Feign组件的使用及参数的传递

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Spring Cloud》。&#x1f3af;&#x1f3af; &am…

浅析观察者模式在Java中的应用

观察者模式&#xff08;Observer Design Pattern&#xff09;,也叫做发布订阅模式&#xff08;Publish-Subscribe Design Pattern&#xff09;、模型-视图&#xff08;Model-View&#xff09;模式、源-监听器&#xff08;Source-Listener&#xff09;模式、从属者&#xff08;D…

强化学习5——动态规划在强化学习中的应用

动态规划在强化学习中的应用 基于动态规划的算法优良 &#xff1a;策略迭代和价值迭代。 策略迭代分为策略评估和策略提升&#xff0c;使用贝尔曼期望方程得到一个策略的状态价值函数&#xff1b;价值迭代直接使用贝尔曼最优方程进行动态规划&#xff0c;得到最终的最优状态价…

【SpringCloud】之配置中心(进阶使用)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringCloud开发之远程消费》。&#x1f3af;&a…

5年经验之谈 —— 探索自动化测试用例设计粒度!

自动化测试用例的粒度指的是测试用例的细致程度&#xff0c;即每个测试用例检查的功能点的数量和范围。 通常&#xff0c;根据测试用例的粒度&#xff0c;可以被分为3种不同的层次&#xff0c;从更低层次的细粒度到更高层次的粗粒度。 第一种&#xff1a;单元测试 - 细粒度 单…

node:全局对象事件环buffer

node&#xff1a;全局对象&事件环&buffer 全局对象 exports/module/require/__dirname/__filename&#xff1a;这些是参数 global全局对象&#xff0c;挂载global上的 process process 进程&#xff0c;代码node服务都是跑在一个进程里面。进程和集群 process上常用属性…

muduo网络库剖析——网络地址InetAddress类

muduo网络库剖析——网络地址InetAddress类 前情从muduo到my_muduo 概要socketaddr_in介绍成员用法 网络地址转换函数 框架与细节成员函数使用方法 源码 前情 从muduo到my_muduo 作为一个宏大的、功能健全的muduo库&#xff0c;考虑的肯定是众多情况是否可以高效满足&#xf…

rime中州韵小狼毫 help lua Translator 帮助消息翻译器

lua 是 Rime中州韵/小狼毫输入法强大的武器&#xff0c;掌握如何在Rime中州韵/小狼毫中使用lua&#xff0c;你将体验到什么叫 随心所欲。 先看效果 在 rime中州韵 输入效果一览 中的 &#x1f447; help效果 一节中&#xff0c; 我们看到了在Rime中州韵/小狼毫输入法中输入 h…

Mediant approximation trick

近似值的一个取值技巧 如果知道一个数值变量的上限和下限&#xff0c;那么有一种快速的方法&#xff0c;快速获取该变量更准确的近似值。 比如&#xff0c;已知变量e的大小范围是19/7 < e < 87/32&#xff0c;就可以快速得到它的近似值。 Suppose you are trying to ap…

Navicat 技术干货 | 如何查看关系型数据库(MySQL、PostgreSQL、SQL Server、 Oracle)查询的运行时间

在数据库优化中&#xff0c;理解和监控查询运行时间是至关重要的。无论你是数据库管理员、开发人员或是参与性能调优的人员&#xff0c;知道如何查看查询运行时间能为你的数据库操作提供有价值的参考。本文中&#xff0c;我们将探索几款热门的关系数据库&#xff08;如 MySQL、…

大模型实战营Day1 书生·浦语大模型全链路开源体系

1.大模型为发展通用人工智能的重要途经 专用模型&#xff1a;针对特定任务解决特定问题 通用大模型&#xff1a;一个模型对应多模态多任务 2.InternLM大模型开源历程 3.InternLM-20B大模型性能 4.从模型到应用&#xff1a;智能客服、个人助手、行业应用 5.书生浦语全链条开源…