一、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 即可把结构体的配置写入到寄存器中。
上一篇:梳理STM32F429之通信传输部分---NO.1 串口通讯
下一篇:再造STM32---第二十一部分:串行FLASH文件系统 FatFs
推荐阅读
史海拾趣
随着国内市场的饱和,APDI决定实施国际化战略,以拓展海外市场。公司首先在欧洲设立了研发中心,与当地高校和研究机构合作,共同开发适应欧洲市场的电子产品。随后,APDI又在亚洲建立了生产基地,利用当地的低成本优势和高效的供应链管理,进一步降低了产品成本,提高了市场竞争力。
在电子行业的快速发展中,Connection One公司始终保持着强烈的创新意识。公司不断投入研发资金,引进高端人才,推动技术创新和产品升级。这种持续创新的精神使得公司在行业中始终保持领先地位,铸就了辉煌的业绩。
这些故事虽然基于虚构情节,但反映了电子行业中企业发展的一些普遍规律。在实际情况中,一个成功的电子企业往往需要具备技术创新能力、市场拓展能力、全球化视野以及持续创新的精神。
在电子行业的激烈竞争中,宜源科技公司始终将技术创新作为公司发展的核心驱动力。公司投入大量研发资源,成功开发出一系列具有自主知识产权的电子产品和解决方案。其中,其独特的智能芯片技术,不仅大幅提升了产品的性能,还降低了生产成本,使得宜源科技在市场中迅速脱颖而出。
随着公司规模的扩大,Concurrent Logic开始寻求国际合作。他们与日本、韩国和欧洲的几家公司签订了技术合作协议,共同开发新一代的并行处理解决方案。这些合作为公司带来了更广阔的市场和更多的资源,推动了技术的进一步创新。
随着电子设备的普及和互联网的发展,Cables To Go公司看到了巨大的市场潜力。公司积极拓展销售渠道,通过线上电商平台和线下实体店相结合的方式,将产品销往全国各地。此外,公司还积极开拓国际市场,与多个国家和地区的代理商建立了合作关系,进一步扩大了市场份额。这种跨越式的市场拓展策略为公司的快速发展奠定了坚实的基础。
ECT在射频连接器领域取得了显著的技术突破。从2006年到2008年,公司开始研发射频同轴连接器,并在2009年实现精密射频同轴连接器的量产,并成功获得专利。这一技术突破为ECT在射频连接器市场赢得了重要地位,也为公司后续的发展奠定了坚实的基础。
近来有很多朋友问及MAP文件,下面我就对MAP文件的一点理解和大家分享。 MAP文件是CCS软件编译后产生的有关DSP用到所有程序、数据及IO空间的一种映射文件。 一、生成方法 MAP文件主要有两种生成方法,一种是由系统自动生成,默认文 ...… 查看全部问答∨ |
CC2500加功率放大加低噪音放大是在CC2500的基础上扩展PA+LNA;CC2500+PA+LNA模块是集FSK/ASK/OOK/MSK.调制方式于一体的收发模块。它提供扩展硬件支持实现信息包处理、数据缓冲、群发射、空闲信道评估、链接质量指示和无线电波唤醒,可以采用曼彻斯特 ...… 查看全部问答∨ |
请教各位,其实我的问题就是要把小信号稳定的放大1000倍,要求这个放大倍数很精确,双级或单级都可以。最好是有高手可以告诉我直接有精密的放大100倍和10倍的芯片。在线等,谢谢啦!… 查看全部问答∨ |
|
在windows mobile下写输入法,那位大哥能给点资料? 在windows mobile下写输入法,那位大哥能给点资料? SIP IME输入法都可以,还想问下大家,sip能切换ime输入法吗?… 查看全部问答∨ |
marvell的cpu智能机板子,要做一个自己的下载工具 email:killbug2004@gmail.com 另外麻烦讲一下基于usb下载的流程 中间有个VerifyImage不懂,文件下载id设置也不太清楚 谢谢达人… 查看全部问答∨ |
EVC编程出现LINK 错误 我不能解决 希望有高人能帮我看看 谢谢了。。 error LNK2019: unresolved external symbol "int __cdecl registerwnd(struct HINSTANCE__ *)" (?registerwnd@@YAHPAUHINSTANCE__@@@Z) referenced in function WinMain ARMV4Rel/mytimetable.exe : ...… 查看全部问答∨ |
1。在仿真中,有些非端口信号,例如SIGNAL ,VARIABLE,在node finder的 all list中 还是没有,没法建立它们的仿真波形,该怎么办,而且有的SIGNAL可以看到,有的看不到,这是为什么?(QUARTUSII) 2。在PROCESS中,这个PROCESS是 TYPE state IS ...… 查看全部问答∨ |
我用1394转接卡接一个摄像头,然后在屏幕上实时的显示摄像头拍得图像,但是在启动初始化的时候(大概10次中有1次),显示在屏幕上的图像错位了,图像的1/3跑到下面去了,而且一直保持这样,要让图像正常只能重启,有人说是同步问题,但我觉得不像, ...… 查看全部问答∨ |