STM32F1的I2C模块协议简介

发布者:学富五车最新更新时间:2023-09-13 来源: elecfans关键字:STM32F1  I2C模块  协议 手机看文章 扫描二维码
随时随地手机看文章

I2C是一种多主从的串行通讯协议。STM32F1的I2C模块支持标速(最高100kHz)和高速(最高400kHz)两种工作模式。


一、I2C协议简介

标准的IIC接口有数据线SDA、时钟线SCL两条总线,只能工作于半双工模式,在设计中,对总线的负载电容有一定的要求,具体请查阅元件的技术手册确定。

IIC的通讯时序如图,通讯电平为正逻辑:

图片

※数据发送的起始和终止信号为:SCL为高时,

起始:SDA下降沿 终止:SDA上升沿

※当总线空闲时,SDA和SCL均为高电平,总线需要外接上拉电阻,阻值5-10k。

※每次发送一字节(8bits)信号,MSB高位先发。

二、I2C通讯时序(使用时以具体被控芯片手册为准)

通讯时序(主机发送若干数据):

※主机引脚配置为open Drain,务必不要内部上拉、下拉

***①保持SCL=1,拉低SDA,产生起始信号。

***②拉低SCL,准备发送数据;

***③将数据高位Shift Out(SDA上),随后拉高SCL。在SCL=1期间SDA电平不能变动。

***④将数据依次输出

***⑤输出最后一位数据且SCL变为低电平后,主机接SDA引脚立即变换为高阻输入模式。

⑥主机向SCL输出一个时钟方波,在方波高位检测从机是否将SDA拉低(即发送ACK);若未收到表明发送未成功。

***⑦当主机检测到SDA被拉低时,表明从机准备好接收下一字节数据。随后主机拉高SCL,从机释放SDA,形成终止信号。若错误,主机也拉高SCL并记录错误。此时SCL=1,SDA=1。***

⑧准备下一次传输。

通讯时序(从机接收若干数据):

①从机引脚均配置为输入模式

***②检测开始信号,随后接收数据(可以通过SCL上升、下降沿触发方式检测校验)

③若接收没有出现错误,从机将SDA配置为开漏,在定义的数据长度(数据位+1ACK)的前一个时钟方波之后(时钟下降沿)拉低SDA发出ACK。若接受错误(例如一个时钟信号上升下降沿SDA数据不同)则不下拉。

④检测到SCL出现上升后,释放SDA。

⑤准备下一次传输。

※IIC数据以1个数据包(主机)+1位ACK(从机)格式传送:

图片

发送地址的最后一位是数据方向位(R/W位),该位用“0”表示主机发送数据,“1”表示主机接收数据(R)。

※当STM32做主机时,在发送地址位后(10位地址模式为首序列最后一位)会根据方向位自动判断进入主发送器模式或主接收器模式**。**

三、STM32 LL库IIC驱动

STM32的I2C模块可以配置为从机输出、从机输入、主机输出、主机输入四种模式。

■主模式时,I2C接口启动数据传输并产生时钟信号。串行数据传输总是以起始条件开始并以停止条件结束。起始条件和停止条件都是在主模式下由软件控制产生。

■从模式时,I2C接口能识别它自己的地址(7位或10位)和广播呼叫地址。软件能够控制开启或禁止广播呼叫地址的识别。

※ SCL时钟信号、起始终止信号由主机输出 , 应答始终由从机应答 ;从机由主机发送地址选中(主机和从机的区别)。

1.IIC时钟配置:

在I2C_CR2寄存器中Freq[5:0]设定该模块的输入时钟( APH1旁路时钟输入,最高36MHz )。输入时钟的频率至少为:

● 标准模式下为:2MHz ● 快速模式下为:4MHz

若使用CubeMX进行模块的配置,则生成的模块初始化函数中自动设置

2.相关寄存器

①自身地址寄存器(I2C_OAR1):

图片

图片

图片

STM32的IIC模块支持双地址模式,即 可以设置两个自身地址 :

自身地址寄存器2(I2C_OAR2):

图片

图片

*②时钟控制寄存器(I2C_CCR): * (CubeMX自动配置)

在I2C_CR2中设置完成模块输入时钟后对SCL输出时钟进行配置

图片

图片

图片

③控制寄存器(I2C_CR1)

图片

图片

图片

图片

图片

④控制寄存器(I2C_CR2)

图片

图片

图片

图片

数据寄存器(I2C_DR)

图片

图片

⑥状态寄存器(I2C_SR1)

图片

图片

PEC校验的使用较为复杂,使用时请具体参看手册

图片

图片

图片

图片

图片

图片

对包序号的判断(第几个包?)从起始条件开始计算。

⑦状态寄存器(I2C_SR2)

图片

图片

图片

图片

图片

3.传输时序(请参考传输时序进行开发)

** ①主发送器模式**

※7位地址最后一位为R/W位,10位帧头最后一位为R/W,此时设置为"0",由本机发送

图片

** ②主接收器模式(主模式下起始、终止条件都由本机发出)**

※7位地址最后一位为R/W位,10位帧头最后一位为R/W,此时设置为"1",由本机发送

图片

** ③从接收器模式**

※地址R/W位非本机发送,由硬件自动比对本机地址判断是否被选中。此时R/W位为"0"

图片

** ④从发送器模式**

※地址R/W位非本机发送,由硬件自动比对本机地址判断是否被选中。此时R/W位为"0"

图片

关于主从模式:

*** ■模块默认处于从模式***

*** ■当本机通过START位主动发送起始条件时,进入主模式***

*** ■当主模式最后一字节传输完成后,由本机置STOP位发送停止条件,进入从模式***

*** ■从模式下模块自动检测总线上的电平变化***
*** ■发送/接收模式的选择通过硬件自动判断R/W实现***

■注意发送/接收地址后,读ADDR才能进入主/从模式下一步的数据传输


LL库函数:


1、初始化结构体LL_I2C_InitTypeDef


typedef struct

{

  uint32_t PeripheralMode;/*

  选择模块工作模式,通过LL_I2C_SetMode()实现

  @ref     LL_I2C_MODE_I2C //I2C模式

           LL_I2C_MODE_SMBUS_HOST //

           LL_I2C_MODE_SMBUS_DEVICE //

           LL_I2C_MODE_SMBUS_DEVICE_ARP //

  */

  uint32_t ClockSpeed;/*

  配置时钟频率(< 400kHz(高速);< 100kHz(标准));通过LL_I2C_SetClockPeriod()、LL_I2C_SetDutyCycle()、

  LL_I2C_SetClockSpeedMode()、LL_I2C_ConfigSpeed()实现

    //示例: 若需要100kHz时钟,则输入100000

  */

  uint32_t DutyCycle;/*

  设置高速模式(仅)下信号占空比;通过LL_I2C_SetDutyCycle()实现 

  @ref     LL_I2C_DUTYCYCLE_2 //低:高=2

           LL_I2C_DUTYCYCLE_16_9 //低:高=16:9

 */

  uint32_t OwnAddress1;/*

  设置自身的主地址,通过 LL_I2C_SetOwnAddress1()实现

  //10位模式最大为0x3FF, 7位最大为0x7F

  ※该结构体及模块初始化函数不提供设置第二地址(副地址)的方式

 */

  uint32_t TypeAcknowledge;/*

  配置ACK使能;通过LL_I2C_AcknowledgeNextData()实现

  @ref     LL_I2C_ACK //在接收到一个字节后返回一个应答(匹配的地址或数据)

           LL_I2C_NACK //无应答

  */

  uint32_t OwnAddrSize;/*

  设置自身地址长度;通过LL_I2C_SetOwnAddress1()实现

  ※在双地址模式下只能设置为7位长度

  @ref     LL_I2C_OWNADDRESS1_7BIT //7位长度

           LL_I2C_OWNADDRESS1_10BIT //10位长度

  */

} LL_I2C_InitTypeDef;

2、工作模式设置


void LL_I2C_SetMode(I2C_TypeDef *I2Cx, uint32_t PeripheralMode);/*

设置模块工作模式

@reg       CR1- >SMBUS、SMBTYPE、ENARP

@ref     LL_I2C_MODE_I2C //I2C模式

           LL_I2C_MODE_SMBUS_HOST //

           LL_I2C_MODE_SMBUS_DEVICE //

           LL_I2C_MODE_SMBUS_DEVICE_ARP //

*/

uint32_t LL_I2C_GetMode(I2C_TypeDef *I2Cx);

3、模块开启/关闭函数


void LL_I2C_Enable(I2C_TypeDef *I2Cx);/*

使能(开启)I2C模块

@reg  CR1- >PE

*/

void LL_I2C_Disable(I2C_TypeDef *I2Cx);/*

禁用(关闭)I2C模块

@reg  CR1- >PE

*/

uint32_t LL_I2C_IsEnabled(I2C_TypeDef *I2Cx);/*

检测I2C模块是否开启

@retval: 1//开启

         0//关闭

*/

4.时钟延长控制(ClockStretching)


参考https://blog.csdn.net/happygaohualei/article/details/52864694


通过将SCL线拉低来暂停一个传输.直到释放SCL线为高电平,传输才继续进行。一般情况是从机在发送过程中将SCL接地,主机无法拉高电平后暂停传输,从机处理完成任务后释放SCL,传输继续。 大多数外设不支持时钟延长功能。


※STM32默认允许时钟延长


void LL_I2C_EnableClockStretching(I2C_TypeDef *I2Cx);/*

使能时钟延长。

@reg    CR1- >NOSTRETCH

*/

void LL_I2C_DisableClockStretching(I2C_TypeDef *I2Cx);/*

禁用时钟延长

@reg    CR1- >NOSTRETCH

*/

uint32_t LL_I2C_IsEnabledClockStretching(I2C_TypeDef *I2Cx);/*

检测是否启用时钟延长

@retval     1//启用

*/

5.自身地址设置


地址在从模式下由硬件自动比较


void LL_I2C_SetOwnAddress1(I2C_TypeDef *I2Cx, uint32_t OwnAddress1, uint32_t OwnAddrSize);/*

设置自身主地址,并设置地址模式(7位或10位)

@reg  ADD0    ADD1_7   ADD8_9   ADDMODE 

@param  OWnAddress//自身主地址

        OwnAddrSize//地址模式(7位或10位),@ref    LL_I2C_OWNADDRESS1_7BIT

                                               LL_I2C_OWNADDRESS1_10BIT

※若启用第二地址,设置为7位地址模式

*/

void LL_I2C_EnableOwnAddress2(I2C_TypeDef *I2Cx);/*

双地址模式(启用第二地址),启用后只支持7位地址模式

@reg  OAR2- >ENDUAL

*/

void LL_I2C_SetOwnAddress2(I2C_TypeDef *I2Cx, uint32_t OwnAddress2);/*

设置第二地址(7位)

*/

void LL_I2C_DisableOwnAddress2(I2C_TypeDef *I2Cx);/*

禁用双地址模式

@reg  OAR2- >ENDUAL

*/

6.广播呼叫控制(General Call)


当本机作为从机接收到地址0x00时,将被选中并发ACK(如果使能ACK),0x00即广播地址。


void LL_I2C_EnableGeneralCall(I2C_TypeDef *I2Cx);/*

使能广播呼叫。

@reg    CR1- >ENGC

*/

void LL_I2C_DisableGeneralCall(I2C_TypeDef *I2Cx);/*

禁用广播呼叫.

@reg    CR1- >ENGC

*/

uint32_t LL_I2C_IsEnabledGeneralCall(I2C_TypeDef *I2Cx);/*

检测是否启用了广播呼叫。

@retval  1//启用

*/

7.模块时钟配置


请在模块关闭的状态下配置*

void LL_I2C_SetClockPeriod(I2C_TypeDef *I2Cx, uint32_t ClockPeriod);/*

配置SCL时钟周期;

@reg    CCR- >CCR

@note  具体配置参见MANUAL的CCR寄存器(前有)

*/

uint32_t LL_I2C_GetClockPeriod(I2C_TypeDef *I2Cx);/*

读取CCR- >CCR的值

*/

void LL_I2C_SetClockSpeedMode(I2C_TypeDef *I2Cx, uint32_t ClockSpeedMode);/*

设置速度模式(标准/高速)

@reg    CCR- >FS

@ref      LL_I2C_CLOCK_SPEED_STANDARD_MODE //标准模式(最高100kHz)

          LL_I2C_CLOCK_SPEED_FAST_MODE //高速模式(最高400kHz)

@note  ※高速模式下可设置信号占空比

*/

void LL_I2C_SetPeriphClock(I2C_TypeDef *I2Cx, uint32_t PeriphClock);/*

设置模块的输入时钟(e.g.36Mhz,84Mhz...);单位Hz,函数自动与10MHz对齐;

@reg  CR2- >FREQ

*/

uint32_t LL_I2C_GetPeriphClock(I2C_TypeDef *I2Cx);/*

读取模块的输入时钟(由上一函数设置)

@reg  CR2- >FREQ =@retval

*/

void LL_I2C_SetDutyCycle(I2C_TypeDef *I2Cx, uint32_t DutyCycle);/*

设置信号占空比(※仅高速模式)

@reg            CCR- >DUTY

@ref     LL_I2C_DUTYCYCLE_2 //低:高=2

         LL_I2C_DUTYCYCLE_16_9 //低:高=16:9

*/

uint32_t LL_I2C_GetDutyCycle(I2C_TypeDef *I2Cx);/*

获取信号占空比(仅高速模式);

@reg            CCR- >DUTY

*/

void LL_I2C_SetRiseTime(I2C_TypeDef *I2Cx, uint32_t RiseTime);/*

设置主模式下SCL的最大上升时间。

@reg    TRISE- >TRISE[5:0]

@note 默认值0x02  计算方法请详细参看MANUAL

*/

uint32_t LL_I2C_GetRiseTime(I2C_TypeDef *I2Cx);/*

获取主模式下SCL的最大上升时间。

@retval  =  TRISE[5:0]

*/

时钟配置整合函数(优先使用):


void LL_I2C_ConfigSpeed(I2C_TypeDef I2Cx, uint32_t PeriphClock, uint32_t ClockSpeed,

uint32_t DutyCycle);/

配置输入时钟、时钟周期、占空比(高速模式下)

*/


8.SMbus部分


暂不补充


9.关键控制


①ACK控制(接收时)


void LL_I2C_AcknowledgeNextData(I2C_TypeDef I2Cx, uint32_t TypeAcknowledge);/

配置应答使能(是否接收到一个数据(地址或数据)后返回一个应答)

@reg CR1->ACK

@ref LL_I2C_ACK //返回应答

LL_I2C_NACK //不返回应答

*/


②生成起始条件与终止条件


void LL_I2C_GenerateStartCondition(I2C_TypeDef I2Cx);/

生成起始条件(S),可与SB配合检测起始条件的生成状况

@reg CR1->START

@note 起始条件发送后START位自动清除

*/

void LL_I2C_GenerateStopCondition(I2C_TypeDef I2Cx);/

发送终止条件(P)

@reg CR1->STOP

@note 终止条件发送后STOP位自动清除

*/


③读取/发送操作


uint8_t LL_I2C_ReceiveData8(I2C_TypeDef I2Cx);/

接收8位数据。

读取一次DR,获得8位数据

*/

void LL_I2C_TransmitData8(I2C_TypeDef I2Cx, uint8_t Data);/

发送8位数据。

向DR写入一个字节

*/


I2C中断

(摘自RM008)

图片

图片

从中可以看出,I2C模块的中断掩码非常少,一旦开启可靠性将大大降低,因此一般不使用中断功能

中断总共有两个入口,条件检测、中断配置类似UART和SPI

中断掩码控制:

void LL_I2C_EnableIT_BUF(I2C_TypeDef I2Cx);/
置位ITBUFEN
*/
void LL_I2C_DisableIT_BUF(I2C_TypeDef I2Cx);/
清零ITBUFEN
*/

void LL_I2C_EnableIT_ERR(I2C_TypeDef I2Cx);/
置位ITERREN
*/
void LL_I2C_DisableIT_ERR(I2C_TypeDef I2Cx);/
清零ITERREN
*/

void LL_I2C_EnableIT_EVT(I2C_TypeDef I2Cx);/
置位ITEVTEN
*/
void LL_I2C_DisableIT_EVT(I2C_TypeDef I2Cx);/
清零ITEVTEN
*/

I2C状态判断 ※在软件方式使用I2C时非常重要

读取状态位判断的格式为 LL_I2C_IsActiveFlag_XXX()

使用请参见前面的时序图。

DMA控制

I2C模块同样可以配置DMA传输,这通常使用在主模式下传输大量数据的情况。

但LL库使用DMA时容易发生通讯错误,因此不推荐使用。


关键字:STM32F1  I2C模块  协议 引用地址:STM32F1的I2C模块协议简介

上一篇:详解STM32的位带操作
下一篇:基于STM32G031开发板的双通道简易示波器设计

推荐阅读最新更新时间:2024-11-11 18:32

Qualcomm和OPPO签订3G/4G 中国专利许可协议
2016年7月31日,Qualcomm Incorporated(NASDAQ: QCOM)与广东欧珀移动通信有限公司(OPPO)宣布达成了新的3G和4G中国专利许可协议。按照协议条款,Qualcomm授予OPPO开发、制造和销售3G(WCDMA及CDMA2000)和4G LTE(包括 三模 GSM、TD-SCDMA和LTE-TDD)终端的付费专利许可。OPPO应支付的专利费用与Qualcomm向中华人民共和国国家发展和改革委员会所提交的整改措施条款相一致。 OPPO知识产权部总监冯英表示: 正是科技的精髓启发了我们从内到外打造至美终端,并符合每个人独特的生活方式。本次许可协议将使我们可以获得移动行业最先进的技术,支持我们为消费
[网络通信]
LIN总线技术及应用——协议规范(三)
  一、调度表(Schedule Table) ——主任务发送报头,从任务用响应来补充报头形成完整的报文。那么报头到底是怎么发送的呢? ——这是在调度表中定义的。   调度表负责调度网络中各报文发送的顺序 调度表为每帧报文分配发送时隙(slot)(发送时隙是报文可以被发送的时间) 不同报文的发送时隙可能不同   报文发送的顺序可以在调度表中设定 调度表在网络系统设计阶段确定 调度表使得LIN通信具有可预测性   切换调度表 主任务可以拥有多个调度表,并在不
[嵌入式]
传高通联芯建广联手签署合资协议,定位低端手机芯片
集微网消息,分析师近来就iPhone 8的物料成本分析,发现各种零组件价格已全面上扬,若加上新增的3D感测模块,成本恐将创下新高。 有关新一代iPhone,目前市场传言可能推出iPhone 7s、iPhone 7s Plus 以及iPhone 8三款,其中以iPhone 8的规格配置最高。 外电报导指出,分析师以前一代iPhone 7 plus为基础,发现iPhone 8光是屏幕成本就已上扬约四成,压力感测模块涨了七成,储存芯片也提高四成,难怪先前传出新一代iPhone价格恐达1,000美元以上 。 由于iPhone 8的屏幕尺寸传言将达5.8寸,材质为OLED,加上要把压力感测Touch ID整合到屏幕内,是屏幕成本大幅上扬的主
[手机便携]
东芝与贝恩牵头财团签芯片业务协议 价值约177亿美元
  新浪科技讯 北京时间9月28日下午消息,据《华尔街日报》网站报道称,东芝签订协议,将闪存芯片业务出售给贝恩资本牵头的财团,金额达2万亿日元(约合177亿美元)。   周四,东芝与包括苹果、戴尔、希捷、日本HOYA、韩国SK海力士在内的集团达成协议,在出售协议完成后,芯片业务仍是东芝关联企业。东芝和贝恩资本希望在3月下旬完成交易。   但该芯片业务另一个合资方——西部数据提起的诉讼仍在进行中,这意味着东芝出售芯片业务一事仍未完结。西部数据认为自己在出售芯片业务上有投票权。另一个问题在于通过反垄断机构的认可,这需要最少半年时间。   东芝因旗下西屋电气申请破产损失惨重,急于出售芯片业务,以获得资金,避免在东京股票交易所被摘牌。
[手机便携]
中控技术与迦智科技签订战略合作协议,加速“AI+机器人”布局
近日,中控技术股份有限(简称“中控技术”)和杭州迦智有限公司(简称“迦智科技”)正式签订战略合作协议,迦智科技CEO陈首先、CTO孙逸超、物流部总经理徐征,中控技术董事长、总裁崔山,中控技术总裁助理石莹、总裁助理谢勇、业务部总裁助理曹焱共同出席签约仪式。 根据协议,双方将依托各自优势,面向海内外联合推动流程工业整体解决方案服务平台建设,共同助力实现工厂的自动化、数字化、智能化生产与管理。 迦智科技(IPLUSMOBOT)是全球智能移动机器人领域的领军企业之一,长期深耕于智能移动机器人领域。在智能制造蓬勃发展的时代背景下,迦智科技依托自身的技术优势,坚持科技创新引领,聚焦研发与行业应用落地的深度融合,形
[机器人]
Google/HTC正式完成协议各自聚焦手机/VR业务
宏达电(HTC)宣布已和Google完成11亿美元合作协议。根据该协议,Google延揽原参与打造Google Pixel手机的HTC成员加入,HTC将其智慧财产权非专属授权予Google使用。就此次交易,HTC将收到Google所支付的11亿美元之交易价金,未来将更聚焦于自有品牌智慧型手机业务及拓展VIVE版图;而Google则专注于手机硬体发展,并将台北作为亚太地区最大的研发基地。 宏达电董事长暨执行长王雪红表示,正式完成协议后,HTC将以自有品牌智慧型手机与虚拟实境系统HTC VIVE,继续引领创新。期待HTC的研究团队,加上聚焦重点营运的策略及挹注的资源,能为全球消费者带来截然不同的行动生活体验。 Google硬体
[手机便携]
RS485协议
RS485缺点: RS485总线是一种常规的通信总线,它不能够做总线的自动仲裁,也就是不能够同时发送数据以避免总线竞争,所以整个系统的通信效率必然较低,数据冗余量较大,对于速度要求高的应用场所不适应用RS485总线。同时由于RS485总线上通常只有一台主机,所以这种总线方式是典型的集中—分散型控制系统。一旦主机出现故障,会使整个系统的通信限于瘫痪状态,因此做好主机的在线备份是一个重要措施。 **传统光电隔离的典型电路: VDD与+5V1(VCC485)是两组不共地的电源,一般用隔离型的DC-DC来实现。通过光耦隔离来实现信号的隔离传输,ISL3152EIBZ与MCU系统不共地,完全隔离则有效的抑制了高共模电压的产生,大大
[嵌入式]
c51单片机实用通信协议
一、基本格式: 通信头- 巴克码- 地址字- 长度字- 命令字- 信息位- 校准字 1. 通信头:占1~8个字节,表通信开始(0x00、0xff不能用作通信头); 2.巴克码:占1字节,一般为0x72,表通信头结束; 3.地址字:表终端的地址,占1字节(0x00作为广播地址); 4.长度字:占1字节,表示从地址字到信息位之间的字节数; 5.命令字:占1字节,指示终端的不同操作; 6.信息位:不定长,从0~252字节; 7.校验位:两个字节,采用和校验及CRC校验。 二、应答 1.如果终端接收正确,则应答ACK;如果终端接收错误,则应答NAK; 2.发送方收到ACK,此次通信结束; 3.发送方收到NAK,重发刚
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved