参考手册:TMS320x2803x, Piccolo Technical Reference Manual.pdf
IIC总线(Inter IC BUS)由 PHILIPS 公司推出。IIC 总线由数据线 SDA 和时钟线 SCL 两条线构成通信电路,连接到总线的器件既可以发送数据,也可以接收数据,每个器件都用唯一的地址标志。
术语 | 描述 |
发送器 | 发送数据到总线的器件 |
接收器 | 从总线接收数据的器件 |
主机 | 初始化发送、产生时钟信号和终止发送的器件 |
从机 | 被主机寻址的器件 |
多主机 | 同时有多于一个主机尝试控制总线,但不破坏报文 |
仲裁 | 是一个在有多个主机同时尝试控制总线,但只允许其中一个控制总线并使报文不被破坏的过程 |
同步 | 两个或多个器件同步时钟信号的过程 |
1.兼容飞利浦半导体 I2C 总线规范(2.1版)
2. 一个
多个 I2C 模块连接示意图I2C 模块时钟经I2C输入时钟 SYSCLK 分频得到,通过配置分频器寄存器计算方式如图中公式所示,为与所有 I2C 协议时钟频率匹配,其模块时钟必须限制在 7-12 MHz,SCL引脚上的主时钟基于 I2C 模块时钟分频得到,计算公式如图所示,I2CCLKL 寄存器中的 ICCL和 I2CCLKH ICCH 位分别代表分频值的低字节部分和高字节部分。
DSP 2803x IIC时钟 I2CPSC 配置分频器寄存器
操作模式 |
描述 |
从接收器模式 | I2C 模块作为从机,接收主机发送的数据 |
从发送器模式 | I2C 模块作为从机,发送数据给主机 |
主接收器模式 | I2C 模块作为主机,接收从机发送的数据 |
主发送器模式 | I2C 模块作为主机,发送控制信息和数据给从机 |
当 IIC 总线上的 IIC 模块被配置成主机时,可由该模块产生起始和停止条件。
如上图所示位 IIC 传输数据的例子。IIC 模块支持传输 1 - 8 位的数据值,图中传送的数据是8位。SDA 数据线上每一位的维持时间相当于SCL的一个脉冲。传输数据时,总是高有效位字节(MSB)开始传送。发送和接收数据的个数没有限制。
选择方法:禁止扩展地址使能位,关闭自由数据格式【I2CMDR.XA = 0 ;I2CMDR.FDF = 0】
如下图所示的7位地址格式中,起始位后的第一个字节包括 7 位的从机地址和 1 位读写选择位。位决定数据传送的方向:
每个字节传输完成后必须插入额外的一个时钟周期应答位(ACK)。若在从机传送第一个字节后,从机产生应答位,则发送器就会发送 n 位数据。 n 是由 I2CMDR 的 BC 位来确定的 1 到 8 位的数。数据发送完成后,接收器产生一个应答位 ACK。
IIC 模块 7 位寻址格式(FDF = 0,XA = 0)选择方法:使能扩展地址使能位,关闭自由数据格式【I2CMDR.XA = 1 ;I2CMDR.FDF = 0】
如下图所示的10位地址格式,类似于 7 位地址格式,但主机通过两个单独字节的传送来发送从机地址。第一个字节包括 11110b、10 位从机地址的两个最高位 MSBs 以及一个读写选择位。第二个字节为 10 位从机地址剩下的 8 位地址。主机一旦向从机发送了第二个字节,就可以写数据,或者通过重复使用开始位(START)来改变数据传送方向。
IIC 模块 10 位寻址格式(FDF = 0,XA = 1)选择方法:向自由数据格式位(FDF)写1【I2CMDR.FDF = 1】
起始位后的第一个字节位数据字节,每个数据字节后插入一个应答位ACK,数据位的长度可位 1 - 8 位(取决于 I2CMDR 中的 BC 位),此格式下不发送地址位和数据方向位。因此,发送器和接收器必须同时支持自由数据格式,并且在整个传输过程中数据的传输方向保持不变。
自由数据格式(FDF = 1)每个数据字节传输结束后,主机可以再次驱动一个起始信号。使用该功能,主机可以与多个从机通信,二不需要通过驱动停止信号来放弃总线控制权。
在 IIC 总线传输过程中,主机每发送一个字节,从机都应该产生一个额外的应答(ACK)或非应答(NACK)信号。
应答信号的产生方式:
当主机完成一个字节数据后在 SCL 低电平期间释放 SDA 数据总线,若没有从机作用,SDA 将被上拉至高电平。此时从机若要发出应答信号就应该在 SCL 时钟线低电平期间将 SDA 数据总线拉低,主机检测到这个低电平即表示从机做出了应答。
如果从机不想做出应答或总线出错,当主机释放 SDA 数据总线后没有从机 SDA 拉低,即表示产生一个非应答(NACK)信号。
非应答信号的主要用处有:
工作在主收模式时,主机接收一定字节的数据后可向从机发送一个非应答(NACK)信号告诉从机不需要再发送新的数据;
工作再主发模式工作时,有一个非应答(NACK)中断可用于主句对NACK位进行处理。
当产生 NACK 响应的时序图上图为一实例:
寻址地址为 0x55 的从机但此从机并不存在,那么主机发送的第一个地址字节后将会释放 SDA 总线,但又没从机拉低 SDA 数据总线,因此产生了一个非应答(NACK)相应。
从时序图可看出,当主机检测到非应答响应时将 SCL 时钟总线拉低,以将阻塞其他设备的操作,所以此时需要进入 NACK 中断进行处理,在中断处理程序中可通过 IRS 位清零从而复位 I2CSTR 状态寄存器,实现 IIC 模块的复位。
SCL 的“线与”特性即是指在 SCL 上首先产生低电平的设备将会控制其他设备。这个下降沿强制其他设备的时钟发生器开始其低电平周期。并且只要有设备的时钟信号为低,则 SCL 一直保持为低,必须等 SCL 被释放后其他设备才能结束它们的低电平周期,开始其高电平周期。SCL 上产生的同步信号中,低电平周期的长度由最慢的设备巨顶,高电平周期的长度由最快的设备决定。
若同时有两个或更多主发送器试图在同一时刻、同一总线上发送数据,则需启动仲裁程序。
当第一个主发送器将 SDA数据线置高时(视作释放 SDA),数据线就会被另一个置 SDA 为低的主发送器所控制。仲裁机制总是将优先权赋予那些发送的数据在二进制形式中值最小的设备。因此,当两个或更多的设备发送相同的首字节,仲裁机制会继续根据随后的字节进行仲裁。
中断请求 | 中断描述 |
XRDYINT | 发送寄存器就绪中断:由于先前的数据已从数据发送寄存器 I2CDXR 转移到发送移位寄存器 I2CXSR 中,数据发送寄存器 I2CDXR 准备好接收新的数据。 |
RRDYINT | 接收寄存器就绪中断:作为接收器时,接收到的新数据已经从接收移位寄存器 I2CRSR 中转存至数据接收寄存器 I2CDRR 中,通过 RRDY_INT 通知 CPU 数据准备好被读取。 |
ARDYINT | 寄存器访问就绪中断:由于先前编程的地址、数据以及命令值已经被使用,I2C 模块寄存器准备好被访问。 |
NACKINT | 非应答条件中断:I2C 模块被配置为主发送机时,当从接收机没有发送应答信号时,主机产生一个非应答信号中断。 |
ARBLINT | 仲裁丢失中断:I2C 模块失去和其他主发送机的仲裁竞争。 |
SCDINT | 检测到停止条件中断:在 I2C 总线上检测到停止条件。 |
AASINT | 被寻址中断:在 I2C 总线上的其他主设备把 I2C 配置为从设备。 |
注意:
除了以上七个基本中断,在 FIFO 模式中,发送和接收 FIFO 队列各有一个 FIFO 模式中断。
这两个 FIFO 中断源集成在一个可屏蔽的 PIE 中断(IC2INT2A)中,中断服务程序可以通过读取 FIFO 状态寄存器来确定中断源。
两种方式:
向 I2CMDR 寄存器中的 IIC 重置位(IRS)写 0 。此方式会将 I2CSTR 中的所有状态位复位至默认状态,同时 IIC 模块会保持禁能,直到 IRS 变为 1 。此时 SDA 数据线和 SCL 时钟线 处于高阻态。
将 CPU 管脚 XRS 脚置 0 ,初始化 DSP 复位,整个 DSP 一直保持复位直至 XRS 脚被拉高。当 XRS 被释放为高电平时,所有的 IIC 模块寄存器被复位至默认值,IRS 位被强制置 0 ,使得 IIC 模块复位,IIC 模块将保持复位直至对 IRS 写 1 。
当配置或重新配置 IIC 模块时,IRS 位必须为 0 。强制 IRS 为 0 还能用来节省CPU耗能和清除错误情况。
如下表所示为 IIC 模块使用的寄存器列表,除了发送移位寄存器( I2CXSR)和接收移位寄存器(I2CRSR)外,所有的寄存器都直接与CPU连接,用户可直接访问。
序号 | 寄存器名 | 地址 | 描述 |
1 | I2COAR | 0x7900 | I2C 模块自身地址寄存器 |
2 | I2CIER | 0x7901 | I2C 模块中断使能寄存器 |
3 | I2CSTR | 0x7902 | I2C 模块状态寄存器 |
4 | I2CCLKL | 0x7903 | I2C 模块低电平时钟分频值寄存器(控制低电平持续时间) |
5 | I2CCLKH | 0x7904 | I2C 模块高电平时钟分频值寄存器(控制高电平持续时间) |
6 | I2CCNT | 0x7905 | 数据计数器寄存器(对输出字节进行计数) |
7 | I2CDRR | 0x7906 | I2C 模块数据接收寄存器( I2C 从总线上接收到一个字节数据后,数据将从 I2CRSR 中转移至 I2CDRR,供 CPU 读取) |
8 | I2CSAR | 0x7907 | I2C 模块从地址寄存器 |
9 | I2CDXR | 0x7908 | I2C 模块数据发送寄存器(数据写入 I2CDXR 后将从转移至 I2CXSR,并逐次转移到 SDA 总线上) |
10 | I2CMDR | 0x7909 | I2C 模块模式寄存器 |
11 | I2CISRC | 0x790A | I2C 模块中断源寄存器(用于查询确切的中断源) |
12 | I2CEMDR | 0x790B | I2C 模块扩展模式寄存器 |
13 | I2CPSC | 0x790C | I2C 模块预分频寄存器( 对 SYSCLKOUT 分频输出到 I2C 模块作为I2C 模块的工作时钟) |
14 | I2CFFTX | 0x7920 | I2C 模块 FIFO 模式下的发送寄存器 |
15 | I2CFFRX | 0x7921 | I2C 模块 FIFO 模式下的接收寄存器 |
注意:IIC 模块的时钟来源由时钟控制寄存器 PCLKCR0 控制,在使用 IIC 模块前需确认 PCLKCR0 中的 IIC 模块的时钟控制位已置1
每次发生 IIC 中断请求时, INTCODE 域会生成一个中断源特征码,通过读取 INTCODE 的值可确定确切的中断源。当 CPU 读取这个寄存器后,该寄存器将被清除,同时还会发生以下事件:
// I2C interrupt vector register bit definitions */
struct I2CISRC_BITS { // bits description
Uint16 INTCODE:3; // 2:0 Interrupt code
Uint16 rsvd1:13; // 15:3 reserved
};
union I2CISRC_REG {
Uint16 all;
struct I2CISRC_BITS bit;
};
// I2C interrupt mask register bit definitions */
struct I2CIER_BITS { // bits description
Uint16 ARBL:1; // 0 Arbitration lost interrupt
Uint16 NACK:1; // 1 No ack interrupt
Uint16 ARDY:1; // 2 Register access ready interrupt
Uint16 RRDY:1; // 3 Recieve data ready interrupt
Uint16 XRDY:1; // 4 Transmit data ready interrupt
Uint16 SCD:1; // 5 Stop condition detection
Uint16 AAS:1; // 6 Address as slave
Uint16 rsvd:9; // 15:7 reserved
};
union I2CIER_REG {
Uint16 all;
struct I2CIER_BITS bit;
};
用于确定发生了哪个中断并读取状态信息。
// I2C status register bit definitions */
struct I2CSTR_BITS { // bits description
Uint16 ARBL:1; // 0 Arbitration lost interrupt
Uint16 NACK:1; // 1 No ack interrupt
Uint16 ARDY:1; // 2 Register access ready interrupt
Uint16 RRDY:1; // 3 Recieve data ready interrupt
Uint16 XRDY:1; // 4 Transmit data ready interrupt
Uint16 SCD:1; // 5 Stop condition detection
Uint16 rsvd1:2; // 7:6 reserved
Uint16 AD0:1; // 8 Address Zero
Uint16 AAS:1; // 9 Address as slave
Uint16 XSMT:1; // 10 XMIT shift empty
Uint16 RSFULL:1; // 11 Recieve shift full
Uint16 BB:1; // 12 Bus busy
Uint16 NACKSNT:1; // 13 A no ack sent
Uint16 SDIR:1; // 14 Slave direction
Uint16 rsvd2:1; // 15 reserved
};
union I2CSTR_REG {
Uint16 all;
struct I2CSTR_BITS bit;
};
其中 BC 位可以控制 IIC 模块的数据位格式
// I2C mode control register bit definitions */
struct I2CMDR_BITS { // bits description
Uint16 BC:3; // 2:0 Bit count
Uint16 FDF:1; // 3 Free data format
Uint16 STB:1; // 4 Start byte
Uint16 IRS:1; // 5 I2C Reset not
Uint16 DLB:1; // 6 Digital loopback
Uint16 RM:1; // 7 Repeat mode
Uint16 XA:1; // 8 Expand address
Uint16 TRX:1; // 9 Transmitter/reciever
Uint16 MST:1; // 10 Master/slave
Uint16 STP:1; // 11 Stop condition
Uint16 rsvd1:1; // 12 reserved
Uint16 STT:1; // 13 Start condition
Uint16 FREE:1; // 14 Emulation mode
Uint16 NACKMOD:1; // 15 No Ack mode
};
union I2CMDR_REG {
Uint16 all;
struct I2CMDR_BITS bit;
};
// I2C extended mode control register bit definitions */
struct I2CEMDR_BITS { // bits description
Uint16 BCM:1; // 0 Bit count
Uint16 rsvd1:15; // 15:1 reserved
};
union I2CEMDR_REG {
Uint16 all;
struct I2CEMDR_BITS bit;
};
// I2C pre-scaler register bit definitions */
struct I2CPSC_BITS { // bits description
Uint16 IPSC:8; // 7:0 pre-scaler
Uint16 rsvd1:8; // 15:8 reserved
};
union I2CPSC_REG {
Uint16 all;
struct I2CPSC_BITS bit;
};
// TX FIFO control register bit definitions */
struct I2CFFTX_BITS { // bits description
Uint16 TXFFIL:5; // 4:0 FIFO interrupt level
Uint16 TXFFIENA:1; // 5 FIFO interrupt enable/disable
Uint16 TXFFINTCLR:1; // 6 FIFO clear
Uint16 TXFFINT:1; // 7 FIFO interrupt flag
Uint16 TXFFST:5; // 12:8 FIFO level status
Uint16 TXFFRST:1; // 13 FIFO reset
Uint16 I2CFFEN:1; // 14 enable/disable TX & RX FIFOs
Uint16 rsvd1:1; // 15 reserved
};
union I2CFFTX_REG {
Uint16 all;
struct I2CFFTX_BITS bit;
};
//----------------------------------------------------
// RX FIFO control register bit definitions */
struct I2CFFRX_BITS { // bits description
Uint16 RXFFIL:5; // 4:0 FIFO interrupt level
Uint16 RXFFIENA:1; // 5 FIFO interrupt enable/disable
Uint16 RXFFINTCLR:1; // 6 FIFO clear
Uint16 RXFFINT:1; // 7 FIFO interrupt flag
Uint16 RXFFST:5; // 12:8 FIFO level
Uint16 RXFFRST:1; // 13 FIFO reset
Uint16 rsvd1:2; // 15:14 reserved
};
union I2CFFRX_REG {
Uint16 all;
struct I2CFFRX_BITS bit;
};