集成电路总线(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 = ®_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。