STM32通关之路——I2C

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

一、I2C协议简介

 1.1、I2C物理层

1.2、协议层

1.2.1、 通讯的起始和停止信号

 1.2.2、数据有效性

1.2.3、 响应

二、I2C特性及架构

 2.1、架构剖析

2.2、I2C初始化结构体

三、I2C——读写EEPROM实验

总结



一、I2C协议简介

I2C通讯协议(Inter - Integrated Circuit) 是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单, 可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路 (IC) 间的通讯。I2C跟USART一样,可以通过分层进行讲解

 1.1、I2C物理层

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

1.2、协议层

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

通讯过程基本结构
  1.  主机的I2C接口产生传输起始信号S,此时连接到I2C总线上的所有从机都会接收到该信号;
  2. 所有从机开始等待主机接下来广播的从机地址信号SLAVE_ADDRESS(7或10位);
  3. 传输方向的选择R/W,该位为 0 时,表示主机向从机写数据;为 1 时,主机由从机读数据;
  4. 从机接收到匹配的地址后,主机或从机会返回一个应答ACK或非应答NACK信号,接收到ACK后,主机才能继续发送或接收数据。

1.2.1、 通讯的起始和停止信号

起始和停止信号

 1.2.2、数据有效性

  • SCL为高电平时SDA表示的数据有效。

1.2.3、 响应

二、I2C特性及架构

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

硬件协议”,STM32 的 I2C 片上外设专门负责实现 I2C 通讯协议,只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU 只要检测该 外设的状态和访问数据寄存器,就能完成数据收发。

 2.1、架构剖析

2.2、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;

三、I2C——读写EEPROM实验

EEPROM 是一种掉电后数据不丢失的存储器,常用来存储一些配置信息,以便系统重新上电的 时候加载之。EEPOM 芯片最常用的通讯方式就是 I2C 协议。EEPROM 可以单个字节擦写。

 I2C流程

  1.  配置通讯使用的目标引脚为开漏模式;
  2. 使能 I2C 外设的时钟;
  3. 配置 I2C 外设的模式、地址、速率等参数并使能 I2C 外设;
  4. 编写基本 I2C 按字节收发的函数;
  5. 编写读写 EEPROM 存储内容的函数;

3.1、EEPROM芯片:

EEPROM设备地址
EEPROM原理图

 按照EEPROM原理图中连接,A0/A1/A2均为0,所以EEPROM的七位地址是:1010000b,即0x50。由于 I2C 通讯时常常是地址跟读写方向连在一起构成一个 8 位数,且当 R/W 位为 0 时,表示写 方向,所以加上 7 位地址,其值为“0xA0”,常称该值为 I2C 设备的“写地址”;当 R/W 位为 1 时,表示读方向,加上 7 位地址,其值为“0xA1”,常称该值为“读地址”。

EEPROM 芯片中还有一个 WP 引脚,具有写保护功能,当该引脚电平为高时,禁止写入数据,当 引脚为低电平时,可写入数据,我们直接接地,不使用写保护功能。

3.2、EEPROM读写时序

原理

 通过I2C接口读取设备X的寄存器Y的值的过程:

  1.  主设备发送起始信号(S);
  2. 发送从设备X地址+读写位0;
  3. 主设备读取 从设备X 应答信号ACK;
  4. 主设备 发送寄存器Y 地址;
  5. 主设备读取 从设备 应答信号ACK;
  6. 主设备重复起始信号(S);
  7. 发送从设备地址+读写位1;
  8. 主设备读取应答信号ACK;
  9. 读取数据;
  10. 从设备发送NACK;
  11. 发送停止信号;

3.3、读写EEPROM:

/********************************************************************
 @function:实现多字节的ATC02的写操作
 @param:
    hi2c:i2c操作句柄;
    DevAddress:从机设备地址;
    MemAddress:从机寄存器地址;
    MemAddSize:从机寄存器地址长度;
    pData:发送数据的起始地址;
    Size:传输数据大小;
    Timeout:操作超时时间;
    
 @retval:
 ********************************************************************/
HAL_StatusTypeDef I2C_Write_Buffer(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
    uint16_t count=0;
    for(count=0; count<Size; count++)
    {
        if(HAL_I2C_Mem_Write(hi2c, DevAddress, MemAddress, MemAddSize, pData, 1, Timeout)==HAL_OK)
        {
             MemAddress ++;
             pData ++;
             HAL_Delay(5);
        }
        else
        {
             printf("i2c write is error \t\n");
             return HAL_ERROR;
        }
    }
    return HAL_OK;
}


/*这里自己实现多字节的ATC02的读操作*/
HAL_StatusTypeDef I2C_Read_Buffer(I2C_HandleTypeDef *hi2c,\
uint16_t DevAddress, uint16_t MemAddress,\
uint16_t MemAddSize, uint8_t *pData, uint16_t Size,\
uint32_t Timeout)
{
       uint16_t count=0;
       for(count=0;count<Size;count ++)
       {
              if(HAL_I2C_Mem_Read(hi2c,DevAddress,MemAddress, MemAddSize,pData,1,Timeout)==HAL_OK)
              {
                     MemAddress ++;
                     pData ++;
                     //HAL_Delay(5);
              }
              else
              {
                     printf("i2c read is error \n");
                     return HAL_ERROR;
              }
       }
       return HAL_OK;
}

总结

I2C读写EEPROM操作,主要通过HAL_I2C_Mem_Write函数按字节写入。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值