IIC总线协议

I2C知识简介之底层协议

在这里插入图片描述
I2C:IIC,Inter-Integrated Circuit,两线式串行总线,由Philips公司开发;是一种半双工通信方式,传输速度由SCL的时钟频率决定:

标准速度100kbps,

快速模式400kpbs,

高速模式可达3.4Mbit/s;

在这里插入图片描述

I2C协议,从以下6个方面去了解:

1)空闲状态;2)开始信号;3)停止信号;4)应答信号;5)数据的有效性;6)数据传输。

1)空闲状态

SDA、SCL同时处于高电平,各个外围器件的输出级场效应管均处于截止状态,释放总线;

2)起始、停止信号

SCL保持高、SDA出现跳变过程时的信号,如下图示:
在这里插入图片描述
因空闲状态时,SCL、SDA都保持高,所以当SDA发生由高变低这个过程时,即表示开始要有动作发生,故此时为起始信号;反之,当SDA由低变高这个过程发生时,又预示着即将进入空闲状态,故表示停止信号(注:此过程中,SCL一直为高)。

//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //设置SDA IO为输出
IIC_SDA = 1;
IIC_SCL = 1;
delay_us(4);
IIC_SDA = 0; //START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL = 0; //钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT(); //设置SDA IO为输出
IIC_SCL = 0;
IIC_SDA = 0; //STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL = 1;
IIC_SDA = 1; //发送I2C总线结束信号
delay_us(4);
}
3)应答信号ACK

发送器每发送完一个字节(8bit),都需要接收器反馈一个应答信号,来表示接收是否成功;若反馈0,则表示应答ACK成功;反之为NACK;
在这里插入图片描述
因发送一个字节需要8个时钟脉冲,所以应答信号发生在第9个时钟脉冲期间;

对于一个有效应答ACK信号的要求:

接收器在第9个脉冲之前的低电平期间,将SDA信号拉低,并且确保在该时钟的高电平期间为稳定的低电平。

在这里插入图片描述
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack (void)
{
u8 ucErrTime = 0;
SDA_IN(); //SDA设置为输入
IIC_SDA = 1; delay_us(1); //将SDA和SCL都拉高
IIC_SCL = 1; delay_us(1);
while (READ_SDA) //等待接收器发出应答信号
{
ucErrTime++;
if(ucErrTime > 250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL = 0; //时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL = 0;
SDA_OUT();
IIC_SDA = 0;
delay_us(2);
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL = 0;
SDA_OUT();
IIC_SDA = 1;
delay_us(2);
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
}
4)数据有效性

I2C传输数据时,只发生在SCL为高电平期间,且SDA数据必需保持稳定;只有在SCL为低电平期间,才允许SDA数据发生变化;

在这里插入图片描述

5)数据传输

数据位的传输是边沿触发,在SCL时钟的同步控制下,逐位地串行传送每一位数据。

//IIC发送一个字节,返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte (u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0; //接低时钟开始数据传输
for (t=0; t<8; t++)
{
if ((txd & 0x80) >> 7)
IIC_SDA = 1;
else
IIC_SDA = 0;

txd <<= 1;
delay_us(2);
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
delay_us(2);
}
}
//读1个字节,ACK=1时,发送ACK;ACK=0时,发送NACK
u8 IIC_Read_Byte (unsigned char ack)
{
unsigned char i, receive = 0;

SDA_IN(); //SDA设置为输入
for (i=0; i<8; i++ )
{
IIC_SCL = 0;
Delay_us(2);
IIC_SCL = 1;
receive <<= 1;
if (READ_SDA)
receive++;
Delay_Us(1);
}
if (!ack)
IIC_NAck(); //发送NACK
else
IIC_Ack(); //发送ACK
return receive;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值