一、简介
IIC(Inter-integerted Circuit)集成电路总线,该通信协议由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场景下使用,传输距离短,任意时刻只能有一个主机的特性。
二、物理层
- IIC通信要求需要两条线路完成数据传输,一条是串行时钟线SCL和一条串行数据线SDA
使用线路:
时钟线 – SCL
数据线 – SDA
(IIC为半双工通信)
- 每个连接到总线上的设备都可以通过唯一的地址和其他器件通信,主机/从机角色和地址可以配置,主机可以作为主机发送器和主机接收器
三、协议内容
IIC通信协议把信息分为两种类型的帧
-
地址帧:用于Master指明信息该发往哪个Slave。(从设备地址)
-
数据帧:由Master发往Slave的数据或是Master接收到来自于Slave的数据(一次读写单位为8bit,高位先发)
四、数据传输状态
(1)数据为有效性规定
-
时钟信号为高电平(High)期间,数据线上的数据必须保持稳定
-
时钟信号为低电平(Low)期间,数据线上方才允许变化
即:数据在时钟线SCL的上升沿到来之前就需准备好,并在下降沿到来之前必须保持稳定
(2)空闲状态
逻辑解析:当IIC总线的数据线SDA和时钟信号当IIC总线的数据线SDA和时钟线SCL同时处于高电平(High)时,规定总线为空闲状态
此时各个器件输出及场效均处在截至状态
即:由两条信号线的上拉电阻把电平拉高
(3)起始信号
逻辑解析:时钟线SCL为高电平期间(High),数据线SDA由高电平向低电平变化(下降沿)表示起始信号
(在时钟线SCL为高电平时,拉低数据线SDA)
程序逻辑实现:
void IIC_Start(void)
{
IIC_SDA_OUT();
IIC_SDA = 1;
IIC_SCL = 1;
delay_us(5);
IIC_SDA = 0; // Start:在SCL为高电平时拉低SDA
delay_us(5);
IIC_SCL = 0;
}
(4)终止信号
逻辑解析:时钟线SCL为高电平期间(High),数据线SDA由低电平向高电平变化(上升沿) 表示终止信号
(在时钟线SCL为高电平时,拉高数据线SDA)
程序逻辑实现:
void IIC_Stop(void)
{
IIC_SDA_OUT();
SCL = 0;
SDA = 0;
delay_us(5);
SCL = 1;
delay_us(5);
SDA = 1; // Stop:在SCL为高电平时,拉高SDA
delay_us(5);
}
(5)应答信号
逻辑解析:发送器每发送一个字节(8bit),就在第 9个时钟脉冲期间释放数据线,由接收器反馈一个应答信号。
- 应答位为低电平(Low Level)时,规定为有效应答位(ACK,简称应答位)
表示接收器已经成功接收了该字节数据
- 应答位为高电平(High Level)时,规定为无效应答位(nACK)
一般表示接收器没有接收成功该字节数据
对反馈有效应答信号的ACK的要求是:
-
接收器在第9个时钟脉冲之前的时钟线SCL低电平期间将数据线SDA拉低(Low),并且确保在该时钟的高电平期间为稳定的低电平(Low Level)
-
如果接收器是Master,则在它收到最后一个字节后发送一个nACK信号,以通知被控发送器结束数据发送,并释放数据线SDA,以便主控制器发送一个停止信号
程序逻辑实现:
// 1、Master接收ACK信号
uint8_t IIC_MasterWaitACK(void)
{
uint8_t uErrTime = 0;
IIC_SDA_OUT();
IIC_SDA = 1;
delay_us(2);
IIC_SCL = 1;
delay_us(2);
IIC_SDA_IN();
while(IIC_SDAin)
{
uErrTime++;
if(uErrTime > 300)
{
IIC_SDA_OUT();
IIC_Stop();
return 1; // 应答失败
}
}
IIC_SDA_OUT();
IIC_SCL = 0;
return 0; // 应答成功
}
// 2、Master发送ACK信号
void Master_SendAck(void)
{
IIC_SCL=0;
IIC_SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
// 3、Master不发送ACK信号
void Master_SendnAck(void)
{
IIC_SCL = 0;
IIC_SDA_OUT();
IIC_SDA = 1;
delay_us(2);
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
}
(6)数据传输格式
字节传输与应答
-
每一个字节必须保证是8bit长度
-
数据传送时先传最高位(MSB)
-
每一个被传送的字节后面都必须跟随1bit的应答位(即每一帧数据共9bit)
在IIC总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制)
即:在时钟线SCL串行时钟的配合下,在数据线SDA上逐位的串行传送每一位数据
数据位传输是边沿触发
(7)总线寻址
IIC协议采用7bit的寻址字节(寻址字节是起始信号的第一个字节)
数据位定义:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
D7 ~ D1位:从机地址
D0位:数据传输方向(读写位)0:表示主机向从机写数据 1:表示主机向从机读数据
主机向从设备中写寄存器(数据格式)
主机向从设备中读寄存器值(数据格式)
文章来源:https://www.toymoban.com/news/detail-625909.html
(8)数据收发
使用IIC通讯协议进行数据的接收与发送逻辑(单字节实现)文章来源地址https://www.toymoban.com/news/detail-625909.html
程序逻辑实现
void IIC_SendByte(uint8_t Data)
{
uint8_t i;
IIC_SDA_OUT();
IIC_SCL = 0;
for(i=0; i<8; i++)
{
IIC_SDA = ((Data&0x80)==0x80)?1:0;
Data <<= 1;
delay_us(2);
IIC_SCL = 1;
delay_us(5);
IIC_SCL = 0;
delay_us(2);
}
}
uint8_t IIC_ReadByte(uint8_t ack)
{
uint8_t i,receive=0;
IIC_SDA_IN();
for(i=0; i<8; i++)
{
IIC_SCL = 0;
delay_us(2);
IIC_SCL = 1;
receive <<= 1;
if(IIC_SDAin)
receive |= 0x01;
delay_us(2);
}
if(!ack)
Master_nAckCTP();
else
Master_AckCTP();
IIC_SDA_OUT();
return receive;
}
到了这里,关于IIC通讯协议的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!