I2C通信在51单片机的应用
I2C简介
- 一种同步半双工带数据应答可以挂载多个设备的通信协议
- 由三个接口组成通信线(WP,SCL,SDA)其中WP为写保护,SCL和SDA是I2C接口
- 在写保护关闭时,SCL和SDA接口电压的高低变化来传输数据
- I2C的多设备挂载图:
通信格式
- I2C分别有六种数据格式:开始信号,结束信号,发送数据,接受数据,发送应答,接受应答
- 以上六种信号可以组成不同的通信需求:
- 主机对存储芯片的写入:开始信号–>发送设备地址–>发送应答–>发送写入地址–>发送应答–>发送写入数据–>发送应答–>发送停止信号
- 主机对存储芯片的读出:开始信号–>发送设备地址–>发送应答–>发送读出数据的地址–>发送应答–>开始信号–>发送设备地址–>读取数据–>接受应答–>发送停止信号
- 主机对存储芯片的写入:开始信号–>发送设备地址–>发送应答–>发送写入地址–>发送应答–>发送写入数据–>发送应答–>发送停止信号
- 在以上的通信流程中可以看出无论是发送还是接受都要客机发送应答或接受应答信号
- 信号传输方式
- 开始信号:SCL处于高电平时,SDA由高到低的变化为开始信号
- 结束信号:SCL处于高电平时,SDA由低到高的变化为结束信号
- 数据基础表示:在SCL处于高电平时SDA处于高电平时输出1,SCL处于高电平时SDA处于低电平时输出0
I2C在51单片机的实现方法
sbit SCL=P*^*//定义SCL引脚(*表示具体引脚数)
sbit SDA=P*^*//定义SDA引脚
void I2C_run(void)//I2C通信开始信号
{
SCL=1;
SDA=1;
SDA=0;
SCL=0;
}
void I2C_stop(void)//I2C通信结束信号
{
SDA=0;
SCL=1;
SDA=1;
}
void I2C_send_byte(unsigned char byte)//I2C发送一字节数据
{
for(unsigned char i=0;i<8;i++)
{
SDA=byte&(0x80>>i)
SCL=1;
SCL=0;
}
}
unsigned char I2C_receive_byte()//I2C读取数据
{
unsigned char i,byte=0x00;
SCL=1;
for(i=0;i<8;i++)
{
SCL=1;
if(SDA)byte|=(0x80>>i)
SCL=0;
}
return byte;
}
void I2C_send_ack(unsigned ack)//I2C发送应答
{
SDA=ack;
SCL=1;
SCL=0;
}
unsigned char I2C_receive_ack(void)//I2C接受应答
{
unsigned char ack;
SDA=1;
SCL=1;
ack=SDA;
SCL=0;
return ack;
}
I2C在AT24C02的应用
#define AT89C02_LOCATION 0xA0
void AT89C02_W(unsigned char location,Data)//提供AT89C02储存地址并在该地址写入data
{
I2C_run();
I2C_send_byte(AT89C02_LOCATION);
I2C_send_ack();
I2C_send_byte(location);
I2C_send_ack();
I2C_send_byte(Data);
I2C_stop();
}
unsigned AT89C02_R(unsigned char location)//提供ATC02储存地址并返回该地址数据
{
unsigned data;
I2C_run();
I2C_send_byte(AT89C02_LOCATION);
I2C_send_ack();
I2C_send_byte(location);
I2C_send_ack();
I2C_run();
I2C_send_byte(AT89C02_LOCATION|0x01);
I2C_send_ack();
data=I2C_receive_byte();
I2C_send_ack(1);
I2C_stop();
return data;
}
在单片机I2C通信还有很多应用用以上六种模块还能配置出不同的玩法。
以上为个人学习记录笔记