I2C 介绍

I2C是一种多主机、两线制、低速串行通信总线,广泛用于微控制器和各种外围设备之间的通信。它使用两条线路:串行数据线(SDA)和串行时钟线(SCL)进行双向传输。

核心特性:

  1. 两线制:I2C 通信只需两条线路:

    • SDA(Serial Data Line):数据线,用于传输数据。
    • SCL(Serial Clock Line):时钟线,由主设备控制,用于同步所有设备上的数据传输。
  2. 多主机和多从机:I2C 总线允许有多个主设备(可以发起通信)和多个从设备(响应主设备的请求)。这使得多个控制器可以管理不同的从设备,增加了系统的灵活性。

  3. 地址分配:每个 I2C 设备都通过一个唯一的地址进行识别。这些地址在设备通信时使用,确保数据包被正确发送到指定的设备。

  4. 简单的连接:由于通信线路数量少,I2C 设备通常易于安装和配置,减少了硬件布局的复杂性。

  5. 同步串行通信:数据传输是同步进行的,意味着数据传输由时钟信号控制,提高了数据传输的可靠性。

数据传输模式:

I2C 支持多种数据传输模式,包括标准模式(100kbps)、快速模式(400kbps)、快速模式加(1Mbps)和高速模式(3.4Mbps)。根据需要选择不同的速率,可以平衡通信速度和系统资源消耗。

应用场景:

I2C 协议在嵌入式系统中非常流行,适用于各种应用,如:

  • 传感器读取:温度、湿度、压力等传感器经常通过 I2C 与微控制器通信。
  • 设备控制:在许多小型设备或计算机系统中,如笔记本电脑,I2C 用于调节音量、亮度、电源管理等。
  • 存储设备:某些类型的 EEPROM 和其他存储设备通过 I2C 接口与主控制器通信。

在普通单片机上的IIC通信可以简化为如下步骤

  • SCL为高电平的时候,SDA由高电平变化到低电平,表示开始传输数据.
  • SCL变低电平,SDA开始不断高低电平表示逻辑0和1来发送数据,共8次.
  • SCL变高,从设备用SDA返回低电平0,则是ACK,表示发送成功,如果SDA是高电平1,则是NACK,表示没发送成功,
  • SCL又变低电平,SDA继续发送数据.
  • 当SCL变高电平的时候,SDA如果由低电平变高电平,则结束.

ArceOS的 I2C 驱动实现

MIO是一个包含多种控制器功能的多路选择控制器,飞腾派的每个MIO均可单独当做UART/I2C。端口功能的选择,可以通过配置creg_mio_func_sel寄存器来实现,配置为00选择I2C,配置为01选择UART。

由MIO控制器来当作IIC来与设备通信,操作会比普通单片机中用GPIO口模拟iic时序要复杂

由MIO控制的I2C操作说明:

1. 初始化

1.1 飞腾派I/O引脚初始化:

初始化I/Opad引脚寄存器,FIOPadConfig是一个配置实例,提供配置信息,包括其基地址和设备ID号,为MIO的初始化做铺垫,
代码由这里跳转

1.2 MIO控制器初始化

先对MIO进行初始化配置,包括功能寄存器地址,MIO寄存器地址以及中断编号
按照之前配置的I/Opad引脚寄存器,来设置 I2C 的 SCL 和 SDA 引脚功能。
设置MIO配置,包括 ID号、MIO基地址、中断号、频率、设备地址 和 传输速率。(这些由FMioLookupConfig来提供不同MIO的配置信息)
代码由这里跳转

1.3 初始化 I2C 配置

I2C配置中包含MIO配置,具体可以见结构体FI2c。首先检查设备是否已经初始化,防止重复初始化。如果设备没有初始化,它会进行去初始化操作,设置设备的配置数据,然后重置设备,最后将设备标记为已就绪状态
代码由这里跳转
最后返回到MIO控制器初始化中,初始化I2C设备中的中断函数

2. 收发数据

2.1 发送数据

代码跳转到这里
这个发送数据函数接收一个buffer用来装要发送的数据,由于是[u8],只有一个u8大小的值,所以buf_len也是1(这份数据只发一次,不重复发)。还接收一个inchip_offset,指从设备内部的偏地址
先通过FI2c对象来判断是否准备好,工作模式是否为主模式 然后启动I2C主设备传输,可以看这里FI2cMasterStartTrans 随后在FIFO不满的情况下,向0x10(IC_DATA_CMD)的bit[7:0]写数据,bit[8]写0表示写以外,向bit[9]写1表示停止。

2.2 接收数据

代码跳转到这里
和发送数据函数一样,接收数据函数接收一个buffer用来装接收到的u8大小的数据,以及buf_len,inchip_offset
先通过FI2c对象来判断是否准备好,工作模式是否为主模式
然后启动I2C主设备传输。
发送读数据命令:向0x10(IC_DATA_CMD)bit[8]写1,表示命令为读操作.
在FIFO不空的情况,读取数据,读最后一个字节数据时要加上停止信号,即除了向0x10(IC_DATA_CMD)的bit[8]仍写1表示读以外,向bit[9]写1表示停止。 最后停止I2C传输,见FI2cMasterStopTrans

I2C 寄存器:见飞腾派软件编程手册P292页

MIO寄存器基地址:

NameOffset
MIO00x000_2801_4000
MIO10x000_2801_6000
MIO20x000_2801_8000
MIO30x000_2801_A000
MIO40x000_2801_C000
MIO50x000_2801_E000
MIO60x000_2802_0000
MIO70x000_2802_2000
MIO80x000_2802_4000
MIO90x000_2802_6000
MIO100x000_2802_8000
MIO110x000_2802_A000
MIO120x000_2802_C000
MIO130x000_2802_E000
MIO140x000_2803_0000
MIO150x000_2803_2000
飞腾小车这里选择的是MIO1作为接口

image