跳转至

集成电路总线(IIC)


1、IIC概述

IIC总线是用于芯片之间连接的一种双线双向的串行总线。IIC总线由一根串行数据线(SDA)和一根串行时钟线(SCL)组成。允许多个Master 和多个Slave设备共享总线。任何时刻总线只能由一个主设备控制,当从设备空闲时总线启动数据传输。它包括总线冲突检查和仲裁机制,以保证当多个主机试图控制总线时,数据不会丢失。该总线特别适合于多个器件之间的短距离通信。I²C总线的标准速率为100kbit/s,快速模式为400kbit/s。

CI14LP芯片共有IIC0、IIC1两组IIC控制器,支持主机/从机、轮询/中断/DMA多种工作模式,并支持SMBus扩展(PEC校验、ARP地址解析)。


2、IIC时序

2.1、基础简介

  • SDA(串行数据线,双向 I/O 线)
  • SCL (串行时钟线,由master提供)
  • 可编程器件既可作为 master 也可作为 slave
  • master(主机,start信号传送,时钟产生者,stop信号传送)
  • slave(从机,被寻址的器件均被认为是从器件)
  • ACK (接收到数据)
  • NACK(未接收到数据、或告诉发送者停止发送)

2.2、I2C总线物理拓扑图

  • 总线可连接多个器件,每个连到总线的器件都有唯一的地址,同一时刻只允许有一个master发起请求。

3、API

3.1 常用接口

函数名 描述
iic_master_polling_init Master 轮询方式初始化(配置速率、超时)
iic_master_polling_send Master 轮询方式发送数据
iic_master_polling_recv Master 轮询方式接收数据
iic_master_txrx_msg Master 多条消息(写后读组合)传输

3.2 中断模式接口

函数名 描述
iic_master_interrupt_init Master 中断方式初始化
iic_master_interrupt_send Master 中断方式发送数据(回调逐字节取数)
iic_master_interrupt_recv Master 中断方式接收数据(回调逐字节收数)
iic_slave_interrupt_init Slave 中断方式初始化(含从机地址)
iic_slave_interrupt_send Slave 中断方式发送数据
iic_slave_interrupt_recv Slave 中断方式接收数据

3.3 DMA模式接口

函数名 描述
iic_dma_config IIC DMA方式初始化(含TX/RX FIFO触发长度)
iic_dma_start 启动一次DMA传输(指定方向)

3.4 SMBus及配置接口

函数名 描述
iic_pec_enable PEC(数据校验)使能
iic_smbus_type SMBus类型(Device/Host)
iic_smbus_mode SMBus/IIC模式选择
iic_arp_enable ARP地址解析使能
iic_config_slave_addr 配置从机地址
iic_filt_width_set SDA/SCL毛刺滤波宽度设置(cycle)
i2c_master_send_recv 兼容旧驱动:先写后读组合传输

4、关键类型

类型 说明
iic_base_t 控制器选择:IIC0、IIC1、IIC_NULL
iic_timeout_t 超时选择:LONG_TIME_OUT(0x5FFFFF)、SHORT_TIME_OUT(0xFFFF)
iic_ack_type_t ACK状态:IIC_ACKTYPE_ERR / ACK / NACK
iic_send_state_t 发送状态:IIC_SENDSTATE_OK / STOP / NOTIFY
iic_txrx_t 传输方向:IIC_M_WRITE、IIC_M_READ
iic_txrxfifolevel_t DMA触发byte长度:IIC_TXRX_FIFO_LEVEL_1 ~ 16
iic_smbus_type_t SMBUS类型:IIC_SMBUS_TYPE_DEVICE / HOST
iic_smbus_mode_t SMBUS模式:IIC_SMBUS_MODE_IIC / SMBUS
iic_txrx_msg_t 多消息传输结构体(buf、size、txrx、read_size/write_size)
master_send_cb_t / master_recv_cb_t 中断模式master发送/接收回调函数指针
slave_send_cb_t / slave_recv_cb_t 中断模式slave发送/接收回调函数指针

SMBUS设备地址默认为 IIC_SMBUS_DEVICE_ADDR(0x61),主机地址为 IIC_SMBUS_HOST_ADDR(0x08)。


5、示例

1) 以下代码以Master轮询方式向从机地址0x50的器件写入10字节数据:

#include "ci14lp_iic.h"

void iic_master_write_demo(void)
{
    char write_buf[10] = {0};
    uint8_t last_ack_flag = 0;

    //IIC0 Master初始化,速率100K,长超时
    iic_master_polling_init(IIC0, 100000, LONG_TIME_OUT);

    //向从机0x50写10字节数据
    iic_master_polling_send(IIC0, 0x50, write_buf, 10, &last_ack_flag);
}

2) 以下代码以Master轮询方式先写入寄存器地址,再读取数据(写后读组合传输):

#include "ci14lp_iic.h"

void iic_master_write_read_demo(void)
{
    char reg_addr = 0x10;
    char read_buf[8] = {0};
    iic_txrx_msg_t msgs[2];

    //第一条消息:写寄存器地址
    msgs[0].buf = &reg_addr;
    msgs[0].size = 1;
    msgs[0].txrx = IIC_M_WRITE;
    msgs[0].write_size = 1;

    //第二条消息:读数据
    msgs[1].buf = read_buf;
    msgs[1].size = 8;
    msgs[1].txrx = IIC_M_READ;
    msgs[1].read_size = 8;

    iic_master_polling_init(IIC0, 400000, LONG_TIME_OUT);
    iic_master_txrx_msg(IIC0, 0x50, msgs, 2);
}

3) 以下代码以Master中断方式接收数据(回调中处理每个字节):

#include "ci14lp_iic.h"

static bool master_recv_process(char data, bool stop)
{
    //处理接收到的每个字节,返回true继续接收
    mprintf("recv: 0x%x\n", (uint8_t)data);
    return true;
}

void iic_master_interrupt_demo(void)
{
    iic_master_interrupt_init(IIC0, 100000, LONG_TIME_OUT);
    iic_master_interrupt_recv(IIC0, 0x50, master_recv_process);
}

6、其它

  • 使用IIC引脚前,需要通过GPIO复用接口(gpio_set_pad_reuse)将对应管脚配置为IIC功能,并将引脚配置为开漏模式(gpio_set_pad_open_drain),外接上拉电阻。
  • 中断模式下需要使能对应中断号(IIC0_IRQn / IIC1_IRQn)并调用 eclic_irq_enable,中断服务函数 iic0_irq_handler / iic1_irq_handler 已在驱动内部实现。
  • 轮询接口在超时(iic_timeout_t)后返回错误,长时间等待建议使用中断或DMA模式。

7、API 参考

本模块接口声明于 driver\ci14lp_chip_driver\inc\ci14lp_iic.h,实现位于 driver\ci14lp_chip_driver\src\ci14lp_iic.c。