嵌入式软件开发必看--常用通讯协议---IIC协议详细介绍-从物理层协议层到代码配置

IIC协议概念

I2C 通讯协议(Inter-Integrated Circuit)是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。
在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和片上外设;STM32 标准库则是在寄存器与用户代码之间的软件层。对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。简单来说物理层规定我们用嘴巴还是用肢体来交流,协议层则规定我们用中文还是英文来交流。
下面我们分别对 I2C 协议的物理层及协议层进行讲解。

I2C 物理层

在这里插入图片描述

物理层的特点

它的物理层有如下特点:
(1) 它是一个支持设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线
中,可连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。
(2) 一个 I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线
(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。
(3) 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之
间的访问。
(4) 总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空
闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
(5) 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用
总线。
(6) 具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式
下可达 3.4Mbit/s,但目前大多 I
2C 设备尚不支持高速模式。
(7) 连接到相同总线的 IC 数量受到总线的最大电容 400p

IIC协议层

协议层I2C 的协议定义了通讯的起始和停止信号、数据有效性、响应、仲裁、时钟同步和地址广播等环节
主机箱从机写/读数据

在这里插入图片描述
在这里插入图片描述

数据由主机发送到从机

数据由主机传输至从机 S : 传输开始信号
SLAVE_ADDRESS: 从机地址
在这里插入图片描述
数据由从机传输至主机 R/W: 传输方向选择位,1 为读,0 为写
A/ A: 应答(ACK)或非应答(NACK)信号
P : 停止传输信号
S 表示由主机的 I2C 接口产生的传输起始信号(S),这时连接到 I2C 总线上的所有
从机都会接收到这个信号。

IIC通讯详细介绍

起始信号产生后,所有从机就开始等待主机紧接下来广播的从机地址信号
(SLAVE_ADDRESS)。在 I2C 总线上,每个设备的地址都是唯一的,当主机广播的地址与某个设备地址相同时,这个设备就被选中了,没被选中的设备将会忽略之后的数据信号。根据 I2C 协议,这个从机地址可以是 7 位或 10 位。在地址位之后,是传输方向的选择位,该位为 0 时,表示后面的数据传输方向是由主机传输至从机,即主机向从机写数据。该位为 1 时,则相反,即主机由从机读数据。从机接收到匹配的地址后,主机或从机会返回一个应答(ACK)或非应答(NACK)信号,只有接收到应答信号后,主机才能继续发送或接收数据。

写数据

若配置的方向传输位为“写数据”方向,即第一幅图的情况,广播完地址,接收到应答信号后,主机开始正式向从机传输数据(DATA),数据包的大小为 8 位,主机每发送完一个字节数据,都要等待从机的应答信号(ACK),重复这个过程,可以向从机传输 N 个数据,这个 N 没有大小限制。当数据传输结束时,主机向从机发送一个停止传输信号§,表示不再传输数据。

读数据

若配置的方向传输位为“读数据”方向,即第二幅图的情况,广播完地址,接收到应
答信号后,从机开始向主机返回数据(DATA),数据包大小也为 8 位,从机每发送完一个数据,都会等待主机的应答信号(ACK),重复这个过程,可以返回 N 个数据,这个 N 也没有大小限制。当主机希望停止接收数据时,就向从机返回一个非应答信号(NACK),则从机自动停止数据传输。

读和写数据

除了基本的读写,I2C 通讯更常用的是复合格式,即第三幅图的情况,该传输过程有
两次起始信号(S)。一般在第一次传输中,主机通过 SLAVE_ADDRESS 寻找到从设备后,发送一段“数据”,这段数据通常用于表示从设备内部的寄存器或存储器地址(注意区分它与 SLAVE_ADDRESS 的区别);在第二次的传输中,对该地址的内容进行读或写。也就是说,第一次通讯是告诉从机读写地址,第二次则是读写的实际内容。以上通讯流程中包含的各个信号分解如下

通讯的起始和停止信号

前文中提到的起始(S)和停止§信号是两种特殊的状态,见图 24-5。
当 SCL 线是高电
平时 SDA 线从高电平向低电平切换,这个情况表示通讯的起始。
当 SCL 是高电平时 SDA 线由低电平向高电平切换,表示通讯的停止。
起始和停止信号一般由主机产生

在这里插入图片描述

数据有效性

I2C 使用 SDA 信号线来传输数据,使用 SCL 信号线进行数据同步。见图 24-6。SDA
数据线在 SCL 的每个时钟周期传输一位数据。传输时,SCL 为高电平的时候 SDA 表示的数据有效,即此时的 SDA 为高电平时表示数据“1”,为低电平时表示数据“0”。当 SCL
为低电平时,SDA 的数据无效,一般在这个时候 SDA 进行电平切换,为下一次表示数据
做好准备。

在这里插入图片描述

地址及数据方向

I2C 总线上的每个设备都有自己的独立地址,主机发起通讯时,通过 SDA 信号线发送
设备地址(SLAVE_ADDRESS)来查找从机。I2C 协议规定设备地址可以是 7 位或 10 位,实际中 7 位的地址应用比较广泛。紧跟设备地址的一个数据位用来表示数据传输方向,它是数据方向位(R/W),第 8 位或第 11 位。数据方向位为“1”时表示主机由从机读数据,该位为“0”时表示主机向从机写数据。见图 24-7在这里插入图片描述

响应

I2C 的数据和地址传输都带响应。响应包括“应答(ACK)”和“非应答(NACK)”两种
信号。作为数据接收端时,当设备(无论主从机)接收到 I2C 传输的一个字节数据或地址后,若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号,发送方会继续发送下一个数据;若接收端希望结束数据传输,则向对方发送“非应答(NACK)”信号,发送方接收到该信号后会产生一个停止信号,结束信号传输。见图
在这里插入图片描述

STM32 的 I2C 特性及架构

如果我们直接控制 STM32 的两个 GPIO 引脚,分别用作 SCL 及 SDA,按照上述信号
的时序要求,直接像控制 LED 灯那样控制引脚的输出(若是接收数据时则读取 SDA 电平),就可以实现 I2C 通讯。同样,假如我们按照 USART 的要求去控制引脚,也能实现 USART通讯。所以只要遵守协议,就是标准的通讯,不管您如何实现它,不管是 ST 生产的控制器还是 ATMEL 生产的存储器, 都能按通讯标准交互。
由于直接控制 GPIO 引脚电平产生通讯时序时,需要由 CPU 控制每个时刻的引脚状态,
所以称之为“软件模拟协议”方式。
相对地,还有“硬件协议”方式,STM32 的 I2C 片上外设专门负责实现 I2C 通讯协议,
只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理 I2C协议的方式减轻了 CPU 的工作,且使软件设计更加简单。

STM32 的 I2C 外设简介

STM32 的 I2C 外设可用作通讯的主机及从机,支持 100Kbit/s 和 400Kbit/s 的速率,支
持 7 位、10 位设备地址,支持 DMA 数据传输,并具有数据校验功能。它的 I2C 外设还支持 SMBus2.0 协议,SMBus 协议与 I2C 类似,主要应用于笔记本电脑的电池管理中,本教程不展开,感兴趣的读者可参考《SMBus20》文档了解

I2C 架构剖析

在这里插入图片描述

STM32外设IIC引脚

在这里插入图片描述

I2C 初始化结构体详解

跟其它外设一样,STM32 标准库提供了 I2C 初始化结构体及初始化函数来配置 I2C 外
设。初始化结构体及函数定义在库文件“stm32f10x_i2c.h”及“stm32f10x_i2c.c”中,编程
时我们可以结合这两个文件内的注释使用或参考库帮助文档。了解初始化结构体后我们就
能对 I2C 外设运用自如了。

 typedef struct {
	uint32_t I2C_ClockSpeed; /*!< 设置 SCL 时钟频率,此值要低于 400000*/
	 uint16_t I2C_Mode; /*!< 指定工作模式,可选 I2C 模式及 SMBUS 模式 */
	 uint16_t I2C_DutyCycle; /*指定时钟占空比,可选 low/high = 2:1 及 16:9 模式*/
	 uint16_t I2C_OwnAddress1; /*!< 指定自身的 I2C 设备地址 */
	 uint16_t I2C_Ack; /*!< 使能或关闭响应(一般都要使能) */
	 uint16_t I2C_AcknowledgedAddress; /*!< 指定地址的长度,可为 7 位及 10 位 */
 } I2C_InitTypeDef;

这些结构体成员说明如下,其中括号内的文字是对应参数在 STM32 标准库中定义的宏:
(1) I2C_ClockSpeed
本成员设置的是 I2C 的传输速率,在调用初始化函数时,函数会根据我们输入的数值
经过运算后把时钟因子写入到 I2C 的时钟控制寄存器 CCR。而我们写入的这个参数值不得高于 400KHz。实际上由于 CCR 寄存器不能写入小数类型的时钟因子,影响到 SCL 的实际频率可能会低于本成员设置的参数值,这时除了通讯稍慢一点以外,不会对 I2C 的标准通讯造成其它影响。
(2) I2C_Mode
本成员是选择 I2C 的使用方式,有 I2C 模式(I2C_Mode_I2C )和 SMBus 主、从模式
(I2C_Mode_SMBusHost、 I2C_Mode_SMBusDevice ) 。I2C 不需要在此处区分主从模式,直接设置 I2C_Mode_I2C 即可。
(3) I2C_DutyCycle
本成员设置的是 I2C 的 SCL 线时钟的占空比。该配置有两个选择,分别为低电平时间
比高电平时间为 2:1 ( I2C_DutyCycle_2)和 16:9 (I2C_DutyCycle_16_9)。其实这两个模式的比例差别并不大,一般要求都不会如此严格,这里随便选就可以。
(4) I2C_OwnAddress1
本成员配置的是 STM32 的 I2C 设备自己的地址,每个连接到 I2C 总线上的设备都要有
一 个 自 己 的 地 址 , 作 为 主 机 也 不 例 外 。 地 址 可 设 置 为 7 位 或 10 位 ( 受 下 面I2C_AcknowledgeAddress 成员决定),只要该地址是 I2C 总线上唯一的即可。
STM32 的 I2C 外设可同时使用两个地址,即同时对两个地址作出响应,这个结构成员
I2C_OwnAddress1 配置的是默认的、OAR1 寄存器存储的地址,若需要设置第二个地址寄存器 OAR2,可使用 I2C_OwnAddress2Config 函数来配置,OAR2 不支持 10 位地址,只有7 位。
(5) I2C_Ack_Enable
本成员是关于 I2C 应答设置,设置为使能则可以发送响应信号。本实验配置为允许应
答(I2C_Ack_Enable),这是绝大多数遵循 I2C 标准的设备的通讯要求,改为禁止应答
(I2C_Ack_Disable)往往会导致通讯错误。
(6) I2C_AcknowledgeAddress
本成员选择 I2C 的寻址模式是 7 位还是 10 位地址。这需要根据实际连接到 I2C 总线上
设备的地址进行选择,这个成员的配置也影响到 I2C_OwnAddress1 成员,只有这里设置成10 位模式时,I2C_OwnAddress1 才支持 10 位地址。配置完这些结构体成员值,调用库函数 I2C_Init 即可把结构体的配置写入到寄存器中

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值