一、IIC总线概述
IIC(Inter-Integrated Circuit)是一种同步、半双工、多主从架构、带数据应答的串行通信协议,由Philips公司开发。核心特点如下:
两根信号线:
SCL
(时钟线)和SDA
(数据线),均配置成开漏输出模式,需外接上拉电阻 (通常4.7kΩ)。多设备支持:支持多个主设备和从设备,通过地址寻址(7位或10位)。
二、51单片机实现IIC通信
实现IIC需要编写程序完成以下核心步骤:
1.起始信号
2.终止信号
3.发送数据
4.读取数据
5.主机应答
6.从机应答
1.起始信号和终止信号
起始信号:SCL为高电平期间,SDA由高电平向低电平变化。
终止信号:SCL为高电平期间,SDA由低电平向高电平变化。
void IIC_Start(void)
{
SDA = 1; // 释放SDA
SCL = 1;
Delay_us();
SDA = 0; // 起始条件
Delay_us();
SCL = 0; // 准备发送数据
}
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
Delay_us();
SDA = 1; // 停止条件
Delay_us();
}
2.发送数据和读取数据
发送数据:SCL低电平期间,主机把数据依次放在SDA上(高位先放),再SCL电平拉高发送数据。这样依次循环8次,即可发送一个字节。
void IIC_SendByte(unsigned char byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 0;
Delay_us();
SDA = byte&(0x80>>i);
Delay_us();
SCL = 1;
Delay_us();
}
}
读取数据:SCL低电平期间,从机把数据依次放在SDA上(高位先放),再SCL电平拉高,主机读取数据。这样依次循环8次,即可接收一个字节。(主机在读取数据之前,需要释放SDA,让SDA=1)
unsigned char IIC_ReceiveByte(void)
{
unsigned char i,byte = 0x00;
SDA = 1;
for(i=0;i<8;i++)
{
SCL = 1;
Delay_us();
if(SDA)
{
byte |=(0x80>>i);
}
SCL = 0;
Delay_us();
}
return byte;
}
3.应答(在SCL高电平期间读取SDA是否应答)
主机应答(主机读取数据)
void IIC_ACK(bit ack)
{
SCL = 0;
Delay_us();
if(ack)
{
SDA = 0;
Delay_us();
}
else
{
SDA = 1;
Delay_us();
}
SCL = 1;
Delay_us();
SCL = 0;
}
从机应答(主机发送数据)
bit IIC_CheckACK(void)
{
bit ack;
SCL = 0;
Delay_us();
SCL = 1;
Delay_us();
if(SDA)
{
ack = 1;
}
else
{
ack = 0;
}
Delay_us();
SCL = 0;
return ack;
}