l 串行总线:一条串行数据线SDA、一条串行时钟线SCL;
l 每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机;
l 真正的多主机总线:如果两个或更多主机同时初始化数据传输可以通过冲突检测和仲裁防止数据被破坏串行的8 位双向数据传输位速率在标准模式下可达100kbit/;快速模式下可达 400kbit/s 高速模式下可达
3.4Mbit/s;
l 片上的滤波器可以滤去总线数据线上的毛刺波保证数据完整;
l 连接到相同总线的 IC 数量只受到总线的最大电容 400pF 限制。
主机是初始化总线的数据传输并产生允许传输的时钟信号的器件;从机是任何被寻址的器件。主机控制整个通信,可随时发起或结束通信;而从机只能被动的响应通信。
发送器在一次通信过程中发送数据到总线的器件;接受器在一次通信过程中从总线上接受数据的器件。主机和从机通信时均可作为发送器或接受器。发送器产生数据,接受器接受数据。发送器和接受器的关系是动态变化的,同一器件(主机或从机)某一时刻可作为发送器,也可在另一时刻作为接受器。由当时数据传输的方向而定。
多主机即同一总线上可连接多个主机进行通信,但某一时刻只允许一个主机控制总线。仲裁指多个主机同时尝试控制总线,由某种机制判定哪个主机获得总线控制权。这是多主机共享总线通信时必须面临的问题。
SDA和SCL都是双向线路,都通过一个电流源或上拉电阻连接到正的电源电压。当总线空闲时,这两条线路都是高电平,连接到总线的器件输出级必须是漏极开路或集电极开路才能执行线与的功能。
SCL主要由主机控制,从机仅在从机忙时拉低SCL通知主机“忙”。
SDA在起始和结束条件时由主机控制,发送字节数据时由发送器控制,发送响应位时由接收器控制。
起始条件:由主机产生,在SCL为高时,产生一个下跳沿。
结束条件:由主机产生,在SCL为高时,产生一个上跳沿。
void I2CStart ()
{
SDA_HIGH();
Delay(2);
SCL_HIGH();
Delay(2);
// SCL为高,SDA从高到低,产生起始条件
SDA_LOW(); /* 产生下降沿,产生起始条件 */
Delay(2);
SCL_LOW();
Delay(2);
}
程序清单 1.2 结束条件产生
void I2CStop ()
{
SDA_LOW();
Delay(1);
SCL_HIGH();
Delay(1);
// IIC忙检测,主机释放SCL,如果此时SCL扔为低,则说明是被从机拉低
while (SCL_STATUS() == 0) {
// 在此加入超时功能。SM59R0XA2 -- 超时时间250ms
}
// SCL为高时,SDA由低变为高,产生停止条件
SDA_HIGH();
Delay(1);
}
SCL为低时,更新数据;SCL为高时,采样数据。
3. 字节格式每次发送8位数据,字节后紧跟响应位,先传MSB。响应位由接收器产生。从总线上接收数据的一方必须拉低SDA以响应(ACK)发送器。
n 当从机作为接收器时,若从机不能接收更多数据,则发送NACK给通知主机停止发送数据。即通知忙。
n 当主机作为接收器读从机数据时,在读取最后一个字节数据后发送NACK给从机,通知从机结束数据发送,释放SDA。
程序清单 1.3 主机写代码
INT8U I2CSendByte (INT8U c)
{
INT8U BitCnt;
INT8U ack;
Delay(2);
SCL_LOW();
for (BitCnt=0;BitCnt<8;BitCnt++) {
// 按字节发送数据,MSB先发送
if( (c<< BitCnt) & 0x80) {
SDA_HIGH(); /* 低电平更改数据 */
} else {
SDA_LOW();
}
Delay(2);
SCL_HIGH(); /* 高电平告知从机接收数据 */
Delay(2);
SCL_LOW();
}
// 释放SDA,释放SCL,接收应答位
SDA_HIGH();
Delay(2);
SCL_HIGH();
Delay(2);
// 读取应答位
if(SDA_STATUS() == I2C_ACK)
ack = I2C_ACK;
elseack = I2C_NACK;
SCL_LOW();
return ack;
}
程序清单 1.3 主机读代码
INT8U I2CRcvByte()
{
INT8U retc;
INT8U BitCnt
Delay(2);
retc=0;
SDA_HIGH(); /*置数据线为输入方式*/
for(BitCnt=0;BitCnt<8;BitCnt++) {
Delay(2); // 拉低以允许数据线的改变
SCL_LOW(); /*置时钟线为低,准备接收数据位*/
Delay(2);
SCL_HIGH();
/*置时钟线为高使数据线上数据有效*/
Delay(2);
// 采样数据
retc =retc << 1;
if(SDA_STATUS())
retc=retc+1; /*读数据位,接收的数据位放入retc中 */
Delay(2);
}
SCL_LOW();
Delay(2)
return(retc);
}
程序清单 1.3 主机发ACK/NACK代码
void I2CAck (INT8U a)
{
Delay(2);
if (a==I2C_ACK) {
SDA_LOW(); /*在此发出应答或非应答信号 */
} else {
SDA_HIGH();
}
Delay(2);
SCL_HIGH();
Delay(2);
SCL_LOW(); /*清时钟线,钳住I2C总线以便继续接收*/
Delay(2);
}
如果从机需要时间完成某些功能(如处理接收到的数据或执行一些操作),可在接收和响应一个字节后,使时钟线SCL保持低电平迫使主机进入等待状态,直至从机准备好接收下一字节数据。相当于实现了主机和从机之间的“同步机制”,避免发送数据过快。
如上所述,IIC中的“忙检测”有两种:n 从机向主机发送NACK指示不要继续发送数据;
n 从机拉低SCK通知主机,从机正忙;
如果两个或多个主机尝试发送信息到总线,在其他主机都产生0的情况下首先产生一个 1 的主机将丢失仲裁。仲裁时的时钟信号是用线与连接到SCL 线的主机产生的时钟的同步结合。
仲裁可以持续多位它的第一个阶段是比较地址位有关的寻址信息。如果每个主机都尝试寻址相同的器件。仲裁会继续比较数据位。如果是主机发送器或者比较响应位。如果是主机接收器,因为I2C总线的地址和数据信息由赢得仲裁的主机决定,在仲裁过程中不会丢失信息。
从机地址由一个固定和一个可编程的部分构成。可编程部分可能由它可使用的管脚决定,该部分地址决定了总线上可挂载的相同器件的数量。
R/W指示读写,为1表示主机读从机,为0时,表示主机写从机。
从机地址 | R/W | 位 |
0000000 | 0 | 广播呼叫地址 |
0000000 | 1 | 起始字节1 |
0000001X | CBUS | 地址2 |
0000010 | X | 保留给不同总线格式 |
0000011 | X | 保留到将来使用 |
00001XX | X | Hs模式主机码 |
11111XX | X | 保留到将来使用 |
11110XX | X | 10位从机寻址 |
7位地址传输模式如下,从机地址决定主机选择要操作的从机。R/W位决定了报文的方向,是读或者写。0表示主机向从机写,1表示主机读从机。此模式下,速度达100KBit/s。
主机发送P终止当前通信;也可发送Sr和重复通信或寻址另一从机继续通信过程。这样就有多种不同的灵活的读写格式。不仅仅是以下几种。
l 主机连续的写从机,从机产生ACk:
l 主机连续的读从机,主机产生ACK和NACK(指示最后一个数据传输):
l 主机改变数据的传输方向,通过发送Sr和重复的从机地址。注意,此时可寻址其它主机通信:
l 需提高IIC的位速度;由原来的100Kbit/s,提高至400KBit/s、3.4MBit/s;
l 扩展地址位数10位,以增加可寻址的器件数;
RP不宜过小,一般不低于1KΩ:电源电压限制了电阻Rp的最小值。一般 IO 端口的驱动能力在2mA~4mA量级。如果RP阻值过小,VDD灌入端口的电流将较大,这导致端口输出的低电平值增大(I2C协议规定,端口输出低电平的最高允许值为0.4V);如果灌入端口的电流过大,还可能损坏端口。故通常上拉电阻应选取不低于1KΩ的电阻(当VDD=3V时,灌入电流不超过 3mA)。
RP不宜过大,一般不高于10KΩ:OD连接方式,信号由低电平变为高电闰时,是通过上拉电阻自动拉高实现,电源通过RP对线上负载电容CL充电,这需要一定的时间,即上升时间。IIC总线规范对上升时间有最大值要求。端口信号的上升时间可近似用充电时间常数RPCL乘积表示。如果RC充电时间常数过大,将使得信号上升沿变化缓慢,达不到数据传输的要求。信号线负载电容CL(对地)由多方面组成,包括器件引脚、PCB信号线、连接器等。如果信号线上挂有多个器件,负载电容也会增大。这也限制了总线上的器件数量。比如总线规定,对于的400kbps速率应用,信号上升时间应小于300ns;假设线上CL为20PF,可计算出对应的RP值为15KΩ。因此一般应用中选取的都是几KΩ量级的上拉电阻,比如都选取4K7的电阻。但是如果通过I/O口驱动使之输出高电低平,则上升时间不受限制。
注意!在使用器件的GPIO内部上拉电阻时,有些MCU的上拉电阻阻值较大,并不适用于IIC总线,因此需要外接阻值较小上拉电阻,而不能因为GPIO内部有上拉电阻而使用该电阻。
上 拉电阻应安置在OD输出端附近。当I2C总线上主从器件(Master & Slave)两端均为OD输出时,电阻放置在信号路径的中间位置。当主设备端是软件模拟时序,而从设备是OD输出时,应将电阻安置在靠近从设备的位置。
文章评论(0条评论)
登录后参与讨论