I2C总线支持任何IC生产过程NMOS CMOS双极性,两线――串行数据 SDA 和串行时钟SCL线在连接到总线的器件间传递信息,每个器件都有一个唯一的地址识别,无论是微控制器、LCD 驱动器、存储器或键盘接口,而且都可以作为一个发送器或接收器。
总线空闲状态 :
SDA :高电平
SCL :高电平
硬件电路:
两线要各外接一个约3~10K欧的上拉电阻
宏定义必要参数:
#define SDA P1_0 //I2C 数据传送位
#define SCL P1_1 //I2C 时钟传送位
#define GuestAddr 0x1D //从机地址
延时函数:
1、
void iic_delay(){//延时约7us
for(i=16;i<16;i--);//延时时间us=(3+5*16)/12 值不可大于255
}
2、
#define iic_delay() Delay_1u(8)
void Delay_1u(uint microSecs)
{
while(microSecs--)
{
/* 32 NOPs == 1 usecs*/
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop");
}
}
起始和终止信号(灰色区域):
void iic_start() //函数功能:I2C通信开始
{
SDA = 1;
iic_delay();
SCL = 1;
iic_delay();
SDA = 0;
iic_delay();
}
void iic_stop() //函数功能:I2C通信停止
{
SDA = 0;
iic_delay();
SCL = 1;
iic_delay();
SDA = 1;
iic_delay();
}
应答信号时序:
void iic_ack() //函数功能:I2C通信查应答位
{
SCL = 1;
SCL = 0;
}
写字节代码:
void iic_write_byte(uchar wdata)//函数功能:向I2C从机写入一个字节
{
uchar i,temp,temp1;
temp1 = wdata;
for (i = 0; i < 8; i++)
{
SCL = 0;
iic_delay();
temp = temp1;
temp = temp&0x80;
SDA = (temp == 0x80? 1: 0);
iic_delay();
SCL = 1;
iic_delay();
SCL = 0;
iic_delay();
temp1 <<= 1;
}
}
读字节代码:
uchar iic_read_byte(void) //函数功能:从I2C从机中读出一个字节
{
uchar x;
uchar data;
for (x = 0; x < 8; x++) {
data <<= 1;
SDA = 1;
iic_delay();
SCL = 0;
iic_delay();
SCL = 1;
iic_delay();
P1DIR &= ~0x01
if(SDA == 1) data |= 0x01;
P1DIR |= 0x01
}
return data;
}
综合应用:
void iic_write(uchar byte_add,uchar wdata)//函数功能:按地址写入一字节数据
{
uchar t;
t = GuestAddr <<1;
/* 第一个字节的头 7 位组成了从机地址,最低位它决定了报文的方向:第一个字节的最低位是 0 表示主机会写信息到被选中的从机 ,1 表示主机会向从机读信息*/
iic_start(); //起始信号
iic_write_byte(t);
iic_ack();
iic_write_byte(byte_add);//内部寄存器地址
iic_ack();
iic_write_byte(wdata);//内部寄存器数据
iic_ack();
iic_stop();
}
uchar iic_read(uchar byte_add) //函数功能:按地址读出一字节数据
{
uchar t;
uchar x;
t = (GuestAddr << 1);
iic_start();
iic_write_byte(t);
iic_ack();
iic_write_byte(byte_add);
iic_ack();
t = (GuestAddr << 1) | 0x01;
/* 第一个字节的头 7 位组成了从机地址,最低位它决定了报文的方向:第一个字节的最低位是 0 表示主机会写信息到被选中的从机 ,1 表示主机会向从机读信息*/
iic_start();
iic_write_byte(t);
iic_ack();
x = iic_read_byte();
iic_ack();
iic_stop();
return x;
}
************************************************************************************************
延时函数参考:https://m.hqew.com/tech/fangan_1647539
来源于课堂整理