目录
IIC基础概念
一、IIC是什么?
IIC(Inter-Integrated Circuit 集成电路总线)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是由数据线 SDA 和时钟 SCL 构成的串行总线,可发送和接收数据。在 CPU 与被控 IC 之间、 IC 与 IC 之间进行双向传送, 高速 IIC 总线一般可达 400kbps 以上。
二、使用步骤
1.IIC时序
I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。 开始信号: SCL 为高电平时, SDA 由高电平向低电平跳变,开始传送数据。
结束信号: SCL 为高电平时, SDA 由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收到数据。 CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号, CPU 接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。
这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要
2.IIC配置代码如下
1.IIC开始与结束信号
根据时序图编写。
void IIC_Start(void)//发送 IIC 开始信号
{
SDA_OUT(); //SDA线输出模式
IIC_SCL=1;
IIC_SDA=1;
delay_us(2);
IIC_SDA =0;
delay_us(2);
IIC_SCL =0; //因为空闲状态是高电平,故拉低接收数据
}
void IIC_Stop(void)//发送 IIC 停止信号
{
SDA_OUT();
IIC_SCL =0;
IIC_SDA =0;
delay_us(2);
IIC_SCL= 1;
IIC_SDA=1; //发送I2C总线结束信号
delay_us(2);
}
2.等待应答信号
/*
返回值:1、接收应答失败
0、接收应答成功
*/
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //等待应答,SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;
return 0;
}
SDA要在 SCL前准备好工作。
确认:所有地址和数据字以8位字的形式串行地进出EEPROM。EEPROM发送一个“0”来确认它已经收到了每个字符。这发生在第9个时钟周期。
3.产生 ACK 应答、Nack应答
/*
Ack产生应答信号:
在IIC_SCL从低电平到高电平期间,SDA为低电平-产生应答,SDA为高电平-不产生应答
*/
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0; //SCL
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;
}
Ack产生应答信号:
在IIC_SCL从低电平到高电平期间,SDA为低电平-产生应答,SDA为高电平-不产生应答
4.IIC读写一个字节
写字节
/*
IIC发送一个字节
返回值:1.有应答
0.无应答
*/
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA = (txd&0x80)>>7;
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();
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();
else
IIC_Ack();
return receive;
}
写数据时,SDA要在 SCL前准备好工作,即写完一个数据时,SCL从低电平到高电平表示数据的写入。