STM32 HAL库 STM32CubeMX — I2C(IIC)

文章目录

  • 一、I2C 协议简介
  • I2C 物理层
  • I2C协议层
  • I2C架构
  • 通讯过程
  • 二、STM32Cube MX配置
  • 三、I2C HAL库函数

  • 一、I2C 协议简介

    I2C 通讯协议(Inter - Integrated Circuit) 也就是IIC;

    由Phiilps 公司开发的,它引脚少,硬件实现简单,可扩展性强,不需要USART、CAN 等通讯协议的外部收发设备。

    I2C协议分为物理层和协议层。

    物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。

    协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。

    简单来说物理层规定我们用嘴巴还是用肢体来交流,协议层则规定我们用中文还是英文来交流。

    I2C 物理层

    I2C

    I2C的物理层有如下特点:

    (1) 它是一个支持设备的总线。“总线”指多个设备共用的信号线。在一个I2C 通讯总线中,可连接多个I2C 通讯设备,支持多个通讯主机及多个通讯从机。

    (2) 一个I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。

    (3) 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。

    (4) 总线通过上拉电阻接到电源。当I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。

    (5) 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。

    (6) 具有三种传输模式:标准模式传输速率为100kbit/s ,快速模式为400kbit/s ,高速模式下可达3.4Mbit/s, 但目前大多I2C 设备尚不支持高速模式。

    (7) 连接到相同总线的IC 数量受到总线的最大电容400pF 限制。

    I2C协议层

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

    主机写数据到从机(写数据)
    主机写数据到从机

    广播完地址,接收到应答信号后,主机开始正式向从机传输数据(DATA),数据包的大小为8 位,主机每发送完一个字节数据;

    要等待从机的应答信号(ACK),重复这个过程,可以向从机传输N 个数据,这个N 没有大小限制;

    当数据传输结束时,主机向从机发送一个停止传输信号§,表示不再传输数据;

    主机由从机中读数据(读数据)

    主机由从机中读数据

    广播完地址,接收到应答信号后,从机开始向主机返回数据(DATA),数据包大小也为8 位,从机每发送完一个数据;

    等待主机的应答信号(ACK),重复这个过程,可以返回N 个数据,这个N 也没有大小限制;

    当主机希望停止接收数据时,就向从机返回一个非应答信号(NACK),则从机自动停止数据传输。

    通讯复合格式(读和写数据)

    通讯复合

    I2C 通讯常用的是复合格式

    该传输过程有两次起始信号(S)。一般在第一次传输中,主机通过SLAVE_ADDRESS 寻找到从设备后,发送一段“数据”,这段数据通常用于表示从设备内部的寄存器或存储器地址(注意区分它与SLAVE_ADDRESS 的区别);

    在第二次的传输中,对该地址的内容进行读或写。也就是说,第一次通讯是告诉从机读写地址,第二次则是读写的实际内容。

    通讯的起始和停止信号

    通讯的起始和停止信号

    当SCL 线是高电平时SDA线从高电平向低电平切换,这个情况表示通讯的起始。
    当SCL 是高电平时SDA 线由低电平向高电平切换,表示通讯的停止。

    起始和停止信号一般由主机产生。

    数据有效性

    数据有效性

    I2C 使用SDA 信号线来传输数据,使用SCL 信号线进行数据同步。

    SDA 数据线在SCL 的每个时钟周期传输一位数据。
    传输时,SCL 为高电平的时候SDA 表示的数据有效,即此时的SDA 为高电平时表示数据“1”,为低电平时表示数据“0”。
    当SCL 为低电平时,SDA 的数据无效,一般在这个时候SDA 进行电平切换,为下一次表示数据做好准备。

    每次数据传输都以字节为单位,每次传输的字节数不受限制。

    地址及数据方向

    地址及数据方向

    I2C 总线上的每个设备都有自己的独立地址,主机发起通讯时,通过SDA 信号线发送设备地址(SLAVE_ADDRESS) 来查找从机。

    I2C 协议规定设备地址可以是7 位或10 位。

    紧跟设备地址的一个数据位用来表示数据传输方向,它是数据方向位(R/),第8位或第11 位。数据方向位为“1”时表示主机由从机读数据,该位为“0”时表示主机向从机写数据。

    读数据方向时,主机会释放对SDA 信号线的控制,由从机控制SDA 信号线,主机接收信号,写数据方向时,SDA 由主机控制,从机接收信号。

    响应

    响应

    I2C 的数据和地址传输都带响应。

    响应包括“应答(ACK)”和“非应答(NACK)”两种信号。

    作为数据接收端时,当设备(无论主从机) 接收到I2C 传输的一个字节数据或地址后,若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号,发送方会继续发送下一个数据;
    若接收端希望结束数据传输,则向对方发送“非应答(NACK)”信号,发送方接收到该信号后会产生一个停止信号,结束信号传输。

    传输时主机产生时钟,在第9 个时钟时,数据发送端会释放SDA 的控制权,由数据接收端控制SDA,若SDA 为高电平,表示非应答信号(NACK),低电平表示应答信号(ACK)。

    I2C架构

    STM32 的I2C 外设可用作通讯的主机及从机,支持100Kbit/s 和400Kbit/s 的速率,支持7 位、10位设备地址,支持DMA 数据传输,并具有数据校验功能。它的I2C 外设还支持SMBus2.0 协议。

    I2C架构

    通讯引脚

    I2C 的所有硬件架构都是根据图中左侧SCL 线和SDA 线展开的(其中的SMBA 线用于SMBUS 的警告信号,I2C 通讯没有使用)。

    STM32 芯片有多个I2C 外设,它们的I2C 通讯信号引出到不同的GPIO 引脚上,使用时必须配置到这些指定的引脚。

    引脚 I2C1 I2C2
    SCL PB6 / PB8(重映射) PB10
    SDA PB7 / PB9(重映射) PB11

    时钟控制逻辑

    SCL 线的时钟信号,由I2C 接口根据时钟控制寄存器(CCR) 控制,控制的参数主要为时钟频率。

    配置I2C 的CCR 寄存器可修改通讯速率相关的参数:
    I2C 通讯的 “标准/快速”模式,这两个模式分别I2C 对应100/400Kbit/s 的通讯速率。
    快速模式下可选择SCL 时钟的占空比,可选Tlow/Thigh=2 或Tlow/Thigh=16/9 模式,我们知道I2C 协议在SCL 高电平时对SDA 信号采样,SCL 低电平时SDA 准备下一个数据,修改SCL 的高低电平比会影响数据采样,但其实这两个模式的比例差别并不大。

    CCR 寄存器中还有一个12 位的配置因子CCR,它与I2C 外设的输入时钟源共同作用,产生SCL 时钟,STM32 的I2C 外设都挂载在APB1 总线上,使用APB1 的时钟源PCLK1,SCL信号线的输出时钟公式如下:

    标准模式:

    Thigh=CCRTPCKL1 Tlow = CCRTPCLK1
    快速模式中Tlow/Thigh=2 时:
    Thigh = CCRTPCKL1 Tlow = 2CCRTPCKL1
    快速模式中Tlow/Thigh=16/9 时:
    Thigh = 9
    CCRTPCKL1 Tlow = 16CCR*TPCKL1

    例如,我们的PCLK1=36MHz,想要配置400Kbit/s 的速率,计算方式如下:
    PCLK 时钟周期:TPCLK1 = 1/36000000
    目标SCL 时钟周期:TSCL = 1/400000
    SCL 时钟周期内的高电平时间:THIGH = TSCL/3
    SCL 时钟周期内的低电平时间:TLOW = 2*TSCL/3
    计算CCR 的值:CCR = THIGH/TPCLK1 = 30

    计算结果得出CCR 为30,向该寄存器位写入此值则可以控制IIC 的通讯速率为400KHz。

    数据控制逻辑

    I2C 的SDA 信号主要连接到数据移位寄存器上,数据移位寄存器的数据来源及目标是数据寄存器(DR)、地址寄存器(OAR)、PEC 寄存器以及SDA 数据线。

    当向外发送数据的时候,数据移位寄存器以“数据寄存器”为数据源,把数据一位一位地通过SDA 信号线发送出去;当从外部接收数据的时候,数据移位寄存器把SDA 信号线采样到的数据一位一位地存储到“数据寄存器”中。

    若使能了数据校验,接收到的数据会经过PCE 计算器运算,运算结果存储在“PEC 寄存器”中。

    当STM32 的I2C 工作在从机模式的时候,接收到设备地址信号时,数据移位寄存器会把接收到的地址与STM32 的自身的“I2C 地址寄存器”的值作比较,以便响应主机的寻址。

    STM32 的自身I2C 地址可通过修改“自身地址寄存器”修改,支持同时使用两个I2C 设备地址,两个地址分别存储在OAR1 和OAR2 中。

    整体控制逻辑

    整体控制逻辑负责协调整个I2C 外设,控制逻辑的工作模式根据我们配置的“控制寄存器(CR1/CR2)”的参数而改变。

    在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR1 和SR2)”,我们只要读取这些寄存器相关的寄存器位,就可以了解I2C 的工作状态。

    除此之外,控制逻辑还根据要求,负责控制产生I2C 中断信号、DMA 请求及各种I2C 的通讯信号(起始、停止、响应信号等)。

    通讯过程

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

    主发送器

    主发送器

    主发送器发送流程:

    (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 设备产生一个停止信号§,这个时候会产生EV8_2 事件,SR1 的TXE 位及BTF 位都被置1,表示通讯结束。
    假如我们使能了I2C 中断,以上所有事件产生时,都会产生I2C 中断信号,进入同一个中断服务函数,到I2C 中断服务程序后,再通过检查寄存器位来判断是哪一个事件。

    主接收器

    主接收器

    主接收器接收流程:

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

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

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

    (4) 发送非应答信号后,产生停止信号( P ),结束传输。

    在发送和接收过程中,有的事件不只是标志了我们上面提到的状态位,还可能同时标志主机状态之类的状态位,而且读了之后还需要清除标志位,比较复杂。

    二、STM32Cube MX配置

    IIC

    STM32的I2C协议也支持SMBus模式(一般用于笔记本电池管理)

    Master features  主模式特性
    I2C Speed Mode: IIC模式设置 快速模式和标准模式。
    I2C Clock Speed: I2C传输速率,默认为100KHz

    Slave features  从模式特性
    Clock No Stretch Mode: 时钟没有扩展模式

    	IIC时钟拉伸(Clock stretching)
    	clock stretching通过将SCL线拉低来暂停一个传输.直到释放SCL线为高电平,传输才继续进行.
    	clock stretching是可选的,实际上大多数从设备不包括SCL驱动,所以它们不能stretch时钟.
    

    Primary Address Length selection: 从设备地址长度 设置从设备的地址是7bit还是10bit 大部分为7bit
    Dual Address Acknowledged: 双地址确认
    Primary slave address:  从设备初始地址

    三、I2C HAL库函数

     //IIC写函数
     HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
    功能:HAL库 IIC写数据
    参数:
    *hi2c 设置使用的IIC 名称 例:&hi2c1
    DevAddress 写入的地址 例 0xA0
    *pData 需要写入的数据的地址
    Size 要发送的字节数
    Timeout 最大传输时间,超过传输时间将自动退出传输函数
    
    //示例: HAL_I2C_Master_Transmit(&hi2c1,0xA0,(uint8_t*)tx_data,100,1000);
    
    //IIC读函数
    HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
    功能:HAL库 IIC读一个字节
    参数:
    *hi2c: 设置使用的是那个IIC 名称 例:&hi2c1
    DevAddress: 读取的地址 例 0xA0
    *pData: 存储读取到的数据的地址
    Size: 接收的字节数
    Timeout: 最大读取时间,超过时间将自动退出读取函数
    
    //示例: HAL_I2C_Master_Receive(&hi2c1,0xA0,(uint8_t*)rx_data,100,1000);
    
    
    HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
    功能:HAL库 IIC写数据函数
    参数: 
    *hi2c: 设置使用的是那个IIC 名称 例:&hi2c1
    DevAddress: 从机设备地址 
    MemAddress:从机寄存器地址
    MemAddSize:从机寄存器地址长度
    *pData: 存储读取到的数据的地址
    Size: 接收的字节数
    Timeout: 最大读取时间,超过时间将自动退出写入函数
    
    
    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 HAL库 STM32CubeMX — I2C(IIC)

    发表评论