IIC协议解析
IIC协议与单总线协议类似,也是一种总线协议,用来主器件与从器件之间相互通信,主要区别就是单总线协议通信只需要一个IO口,而IIC协议需要两根线,一根时钟线(SCL),一根数据线(SDL)来进行通信。 IIC通信速率比单总线协议更高。
蓝桥杯板上的PCF8591(AD/DA)与AT24C02(EEPROM)就是使用的IIC协议,也都挂在同一个引脚上。这篇博客也是为了后面使用这两个芯片而准备的。
蓝桥杯比赛中也想单总线一样,IIC也会提供相应的驱动代码,我们只需要会使用就可以了,所以也不进行过多讲解,IIC协议简单总结如下:
时钟信号SCL为高时,SDA必须是稳定的,SCL为低时,SDA上的电平才能够变化
写数据时,SCL为低时,改变SDA
读数据时,SCL为高时,读取IO电平
PS:这里挂一个TI公司写的IIC文档,要比我专业和详细很多很多。
链接:https://pan.baidu.com/s/1aM3p0VIrWTdifxXuZxgaLw
提取码:1815
IIC驱动代码
以下是比赛中会提供的IIC驱动代码
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
#ifndef _IIC_H
#define _IIC_H
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
#endif