历史上的今天
返回首页

历史上的今天

今天是:2024年09月28日(星期六)

2019年09月28日 | 梳理STM32F429之通信传输部分---NO.2 硬件IIC

2019-09-28 来源:eefocus

一、STM32 的 I2C 特性及架构:

只要遵守协议,就是标准的通讯,不管如何实现它,不管是 ST 生产的控制器还是 ATMEL 生产的存储器, 都能按通讯标准交互。


由于直接控制 GPIO 引脚电平产生通讯时序时,需要由 CPU 控制每个时刻的引脚状态,所以称之为“软件模拟协议”方式。


相对地,还有“硬件协议”方式, STM32 的 I2C 片上外设专门负责实现 I2C 通讯协议,只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来, CPU只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理 I2C协议的方式减轻了 CPU 的工作,且使软件设计更加简单。


1、STM32 的 I2C 外设简介:


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


2、STM32 的 I2C 架构剖析:


(1)通讯引脚:


 I2C 的所有硬件架构都是根据 SCL 线和 SDA 线展开的。 STM32 芯片有多个 I2C 外设,它们的 I2C 通讯信号引出到不同的 GPIO 引脚上,使用时必须配置到这些指定的引脚,见下表。关于GPIO 引脚的复用功能,可查阅《STM32F4xx 规格书》,以它为准。


(2)时钟控制逻辑:


SCL 线的时钟信号,由 I2C 接口根据时钟控制寄存器(CCR)控制,控制的参数主要为时钟频率。配置 I2C 的 CCR 寄存器可修改通讯速率相关的参数:可选择 I2C 通讯的“标准/快速”模式,这两个模式分别 I2C 对应 100/400Kbit/s 的通讯速率。


(3)数据控制逻辑:


I2C 的 SDA 信号主要连接到数据移位寄存器上,数据移位寄存器的数据来源及目标是数据寄存器(DR)、地址寄存器(OAR)、 PEC 寄存器以及 SDA 数据线。当向外发送数据的时候,数据移位寄存器以“数据寄存器”为数据源,把数据一位一位地通过 SDA 信号线发送出去;当从外部接收数据的时候,数据移位寄存器把 SDA 信号线采样到的数据一位一位地存储到“数据寄存器”中。若使能了数据校验,接收到的数据会经过 PCE 计算器运算,运算结果存储在“PEC 寄存器”中。当 STM32 的 I2C 工作在从机模式的时候,接收到设备地址信号时,数据移位寄存器会把接收到的地址与 STM32 的自身的“ I2C 地址寄存器”的值作比较,以便响应主机的寻址。 STM32 的自身 I2C 地址可通过修改“自身地址寄存器”修改,支持同时使用两个 I2C 设备地址,两个地址分别存储在 OAR1 和 OAR2 中。


(4)整体控制逻辑:


整体控制逻辑负责协调整个 I2C 外设,控制逻辑的工作模式根据我们配置的“控制寄存器(CR1/CR2)”的参数而改变。在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR1 和 SR2)”,我们只要读取这些寄存器相关的寄存器位,就可以了解 I2C的工作状态了。除此之外,控制逻辑还根据要求,负责控制产生 I2C 中断信号、 DMA 请求及各种 I2C 的通讯信号(起始、停止、响应信号等)。


3、通讯过程:


 使用 I2C 外设通讯时,在通讯的不同阶段它会对“状态寄存器(SR1 及 SR2)”的不同数据位写入参数,我们通过读取这些寄存器标志来了解通讯状态。


① 主发送器

下图中的是“主发送器”流程,即作为 I2C 通讯的主机端时,向外发送数据时的过程。


主发送器发送流程及事件说明如下:

(1) 控制产生起始信号(S),当发生起始信号后,它产生事件“EV5”,并会对 SR1 寄存器的“ SB”位置 1,表示起始信号已经发送;

(2) 紧接着发送设备地址并等待应答信号,若有从机应答,则产生事件“ EV6”及“ EV8”,这时 SR1 寄存器的“ADDR”位及“ TXE”位被置 1, ADDR 为 1 表示地址已经发送, TXE 为 1 表示数据寄存器为空;

(3) 以上步骤正常执行并对 ADDR 位清零后,我们往 I2C 的“数据寄存器 DR”写入要发送的数据,这时 TXE 位会被重置 0,表示数据寄存器非空, I2C 外设通过SDA 信号线一位位把数据发送出去后,又会产生“ EV8”事件,即 TXE 位被置 1,重复这个过程,就可以发送多个字节数据了;

(4) 当我们发送数据完成后,控制 I2C 设备产生一个停止信号(P),这个时候会产生EV2 事件, SR1 的 TXE 位及 BTF 位都被置 1,表示通讯结束。假如我们使能了 I2C 中断,以上所有事件产生时,都会产生 I2C 中断信号,进入同一个中断服务函数,到 I2C 中断服务程序后,再通过检查寄存器位来了解是哪一个事件。

② 主接收器:

再来分析主接收器过程,即作为 I2C 通讯的主机端时,从外部接收数据的过程,见下图:

主接收器接收流程及事件说明如下:

(1) 同主发送流程,起始信号(S)是由主机端产生的,控制发生起始信号后,它产生事件“ EV5”,并会对 SR1 寄存器的“ SB”位置 1,表示起始信号已经发送;

(2) 紧接着发送设备地址并等待应答信号,若有从机应答,则产生事件“ EV6”这时SR1 寄存器的“ ADDR”位被置 1,表示地址已经发送。

(3) 从机端接收到地址后,开始向主机端发送数据。当主机接收到这些数据后,会产生“ EV7”事件, SR1 寄存器的 RXNE 被置 1,表示接收数据寄存器非空,我们读取该寄存器后,可对数据寄存器清空,以便接收下一次数据。此时我们可以控制 I2C 发送应答信号(ACK)或非应答信号(NACK),若应答,则重复以上步骤接收数据,若非应答,则停止传输;

(4) 发送非应答信号后,产生停止信号(P),结束传输。在发送和接收过程中,有的事件不只是标志了我们上面提到的状态位,还可能同时标志主机状态之类的状态位,而且读了之后还需要清除标志位,比较复杂。我们可使用STM32 标准库函数来直接检测这些事件的复合标志,降低编程难度。


二、I2C 初始化结构体详解:

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


typedef struct {

uint32_t I2C_ClockSpeed; /*!< 设置 SCL 时钟频率,此值要低于 40 0000*/

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 位地址。


(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 即可把结构体的配置写入到寄存器中。

推荐阅读

史海拾趣

Blue Giga公司的发展小趣事

2015年,Silicon Labs(芯科科技有限公司)宣布收购Blue Giga。这一收购对于双方来说都是一个重要的里程碑。Silicon Labs通过收购获得了Blue Giga的先进技术和广泛的产品线,进一步增强了其在物联网和无线连接领域的竞争力。而Blue Giga则借助Silicon Labs的全球资源和市场渠道,实现了更快速的发展。

DURATOOL公司的发展小趣事

人才是企业发展的第一资源。DURATOOL公司一直高度重视人才的培养和引进。公司建立了一套完善的人才选拔和培养机制,通过内部培训、外部招聘等方式不断吸纳优秀人才加入公司。同时,公司还为员工提供了广阔的发展空间和良好的福利待遇,激发了员工的积极性和创造力。这些举措使得DURATOOL公司拥有一支高素质、专业化的员工队伍,为企业的发展提供了有力的人才保障。

台湾美丽微(FMS)公司的发展小趣事

近年来,FTDI通过战略并购进一步拓展了其业务领域。例如,电连技术通过发行股份及支付现金的方式收购了FTDI的控股权,这一举措不仅使电连技术在产品和客户层面实现了更完整的布局,也增强了其在汽车电子、物联网、工业产品、医疗设备等多个领域的市场竞争力。FTDI凭借其在USB桥接芯片领域的深厚积累和技术优势,为电连技术的业务扩展提供了有力支持,共同推动了公司在全球电子元件产业的持续发展。

Globaltech Semiconductor Co Ltd公司的发展小趣事

近年来,全球半导体行业面临了诸多挑战,包括供应链紧张、技术迭代加速等。面对这些挑战,Globaltech积极调整战略,加强与上游供应商和下游客户的沟通与合作,确保供应链的稳定。同时,公司还加大了对新技术和新产品的研发投入,以应对行业变化带来的挑战。通过这些努力,Globaltech不仅成功应对了行业挑战,还实现了业务的持续增长。

DATEL Inc公司的发展小趣事

随着公司业务的不断扩展,DATEL Inc.开始实施全球化战略。公司积极开拓国际市场,与全球各地的合作伙伴建立了紧密的合作关系。通过引进国际先进技术和管理经验,DATEL Inc.的产品质量和服务水平得到了进一步提升。同时,公司还加强了对海外市场的营销和推广力度,成功将DATEL Inc.的品牌推向了全球。

Hamamatsu公司的发展小趣事

进入21世纪,随着电子医疗的兴起,DATEL Inc.看到了新的发展机遇。公司开始研发适用于医疗领域的数据采集产品,如医用传感器、生命体征监测仪等。通过与医疗机构紧密合作,DATEL Inc.成功推出了一系列高性能、高可靠性的医疗数据采集产品,为医疗行业的数字化转型做出了重要贡献。

问答坊 | AI 解惑

PSPICE电子线路仿真详细资料!!!

这个十分的精典.... 里面详细介绍了元件模型的建立...以及各电源模型的超详细介绍...最基础的东西... 是国内的ORCAD书中没有介绍的....…

查看全部问答>

博客大赛要开始啦!希望大家多多支持我!为大赛准备,耶!

大家好!我是jxb01033016,我的博客开通啦!希望大家多给我踩踩!!为eeworld博客加油,喝彩!耶! 下面都是我的个人作品哦,希望大家喜欢! 将找工作坚持到底!!!(原创)https://home.eeworld.com.cn/?uid-445-action-viewspace-itemid-9022 ...…

查看全部问答>

绝版路由器演示程序

绝版路由器演示程序…

查看全部问答>

LED驱动隔离式低成本延长LED寿命方案-省电解电容

隔离式LED驱动低成本方案正在研究中,预计今年6月出炉,届时将有省却电解电容方案;并可延长LED电源寿命 此帖光注于此方案的时刻进展中。。。 有知道此消息的回复一下;…

查看全部问答>

中颖单片机在PROTUES中仿真

    中颖单片机在PROTUES中仿真时,找不到相应的 元件,怎么办,会不会像protel中可自创元件库呢?     如何在PROTUES中建自己的元件库?请大虾们指点!!!!…

查看全部问答>

J-Link LoadImage是老是提示 Write Memory error @ address 0x600CAB88

Write Memory error @ address 0x600CAB88, word access: Memory access timeout. 大家帮忙下啊,都快被这个搞死人了,调试不了。…

查看全部问答>

PNG双缓冲问题,为什么我的图片不能显示呢??

int width= dstRc.right-dstRc.left,                                         heigth = dstRc.top-dstRc.bottom;       ...…

查看全部问答>

已有.mms文件,如果通过GPRS模块发出去呢?

看了网上的文章,找了nowsms软件,已经生成了.MMS文件,就是MMS的PDU,上传到手机后可以通过手机可以发送出去 那么,怎么通过GPRS模块发送呢? 我用sim300模块的cipsend命令,在.MMS文件数据前加了如下的POST信息 POST mmsc.monternet.com HTTP1 ...…

查看全部问答>

关于单片机红外传输

最近在搞山东省电子设计大赛,遇到需要使用红外的题目,但是自己不懂,没用过。。。 所以向大家求助: 求助51单片机红外发射和接收的电路图!  …

查看全部问答>