文章目录
👉:I2C协议介绍请看:I2C协议
一、简介
I2C是一个低速、多master多slave的单端串行数据总线,有两根线(SCL串行时钟线和SDA串行数据线)构成,高速模式可达到3.4MHz的传输速率,最高支持5MHz传输(utra-fast mode)。
应用的例子:
- 可以用于EEPROM中
- 控制小的OLED和LCD显示屏
- 可以作为PCI 和 PCIe的配置接口
- 用于常用的低速DACs和ADCs接口
- 调节显示设备的色彩、对比度等配置
- 音频设备的音量调节
- 电源模块的管理等
二、设计架构
这是一个简单的I2C平台,如下图所示结构:
- APB接口,接收来自APB总线的数据和地址;
- Prescale寄存器,对系统时钟分频,控制产生SCL线的时钟模块;
- 指令寄存器,控制读写方向,以及要访问的slave地址;
- 状态寄存器;
- 控制寄存器,控制中断产生和是否使能I2C;
- Transmit寄存器,寄存从APB总线过来的传输数据;
- Receive寄存器,寄存从I2C slave读取的数据;
- 数据IO移位寄存器,连接到Transmit寄存器和Receive寄存器上,写操作时,将APB发送过来的并行数据转换成串行数据,读操作时,将I2C的SDA线上的串行数据转换成并行数据发送到APB线上。
- Byte指令控制器,
- bit 指令控制器,
PS:为什么UART有独立的 write_data_buffer 和 read_data_buffer,而 i2c 可以只用一个 shift_register 连接到接收和发送的数据寄存器上?因为UART是一个全双工的总线,可以读写同时进行,而 I2C 是一个半双工的总线,读写不能同时进行,要么是读操作,要么是写操作。
三、I2C的PAD设计
I2C是一个双向PAD,I2C上的设备是漏极开路,并通过上拉电阻接到SCL和SDA线上。如下图所示:
解释上图:
- scl_o 和 sda_o 是接的 1’b0,scl_i 和 sda_i 是接的 1’bz,为高阻态
- 当 scl_en_o 和 sda_en_o 为 1’b0 时,此时开关被打开,SCL线被置为低;
- 当 scl_en_o 和 sda_en_o 为 1’b1 时,此时开关关闭,向SCL线输出一个高阻态,通过上拉电阻作用将SCL或SDA线置1;
PS:I2C上连接的设备是有上拉电阻的处理,具有线与的功能。协议上可以看:I2C为什么要线与?为什么要上拉?。
四、寄存器的配置
如下是对寄存器的设计,
名称 | 偏移地址 | 位宽 | 访问属性 | 复位值 | 描述 |
---|---|---|---|---|---|
PRElo | 0x00 | 8 | RW | prescale的低8位 | |
PREhi | 0x01 | 8 | RW | prescale的高8位 | |
CTR | 0x02 | 8 | RW | 控制寄存器 | |
TXR | 0x03 | 8 | W | 发送寄存器 | |
RXR | 0x03 | 8 | R | 接收寄存器 | |
CR | 0x04 | 8 | W | 指令寄存器 | |
SR | 0x04 | 8 | R | 状态寄存器 |
1. Prescale 寄存器( PRElo、PREhi )
Prescale 寄存器对时钟的分频关系,如下:
用5倍的SCL时钟来进行分频,如果系统时钟是 32 MHz,期待的SCL时钟是 100 KHz,那么有公式:
分频系数 = 32 MHz/ (5 * 100 KHz) -1 = 63(dec) = 3F (Hex)
注:只有在I2C使能关闭时才能改变 prescale 的值
2. 控制寄存器(CTR)
Bits位 | 命名 | 访问属性 | 描述 |
---|---|---|---|
7 | I2C_EN | RW | I2C使能。当置为1,则启动 I2C;当置为0,则关闭 I2C; |
6 | INTR_EN | RW | I2C中断使能。当置为1,则使能 I2C中断;当置为0,则关闭 I2C中断; |
5:0 | RW | 保留域 |
3. Transmit寄存器(TXR)
Bits位 | 命名 | 访问属性 | 描述 |
---|---|---|---|
7:1 | DATA | W | APB端写入的数据 |
0 | RW | W | RW位。当置为1,则从slave中读取;当置为0,则想slave中写入; |
注:
- 如果是传输的是数据,这8位合在一起刚好是一个byte的数据;
- 如果传输的是地址,则前高7位是地址,最低位R/W位(读写方向位);
- 关于I2C使用10bit地址访问可以看:10bit地址读写;
4. Recieve寄存器(RXR)
Bits位 | 访问属性 | 描述 |
---|---|---|
7:0 | R | 从I2C读取的数据 |
5. 状态寄存器(SR)
Bits位 | 命名 | 访问属性 | 描述 |
---|---|---|---|
7 | ACK | R | 接收数据时回复 |
6 | BUSY | R | I2C 总线处于busy状态。当I2C总线发出 START条件时,为1;当I2C总线发出 STOP条件时,为0; |
5 | ARB_LS | R | master仲裁失败,未获取总线权限。仲裁失败的原因:1.总线产了STOP条件,但没有请求; 2.master驱动SDA为高,但是发现SDA为低; |
4:2 | R | 保留域 | |
1 | TRANS_STATUS | R | 传输状态。为1表示传输正在进行;为0表示传输完成 |
0 | INTR_STATUS | R | 中断指示。只有当CTR寄存器的中断使能打开,中断信号拉起的条件:1.1个byte的数据传输完成;2.仲裁失败 |
6.指令寄存器(CR)
Bits位 | 命名 | 访问属性 | 描述 |
---|---|---|---|
7 | ACK | R | 接收数据时回复 |
6 | BUSY | R | I2C 总线处于busy状态。当I2C总线发出 START条件时,为1;当I2C总线发出 STOP条件时,为0; |
5 | ARB_LS | R | master仲裁失败,未获取总线权限。仲裁失败的原因:1.总线产了STOP条件,但没有请求; 2.master驱动SDA为高,但是发现SDA为低; |
4 | R | 保留域 | |
3 | R | 保留域 | |
2 | R | 保留域 | |
1 | TRANS_STATUS | R | 传输状态。为1表示传输正在进行;为0表示传输完成 |
0 | INTR_STATUS | R | 中断指示。只有当CTR寄存器的中断使能打开,中断信号拉起的条件:1.1个byte的数据传输完成;2.仲裁失败 |
四、RTL代码
【持续更新中…】