扩展:51单片机配置I2C及其简单应用
扩展:51单片机配置I2C及其简单应用
1. I2C协议简介
I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA)。I2C是总线结构,1个Master,1个或多个Slave,各Slave设备以7位地址区分,地址后面再跟1位读写位,表示读(=1)或者写(=0),所以我们有时也可看到8位形式的设备地址,此时每个设备有读、写两个地址,高7位地址其实是相同的。
I2C数据格式如下:
无数据:SCL=1,SDA=1;
开始位(Start):当SCL=1时,SDA由1向0跳变;
停止位(Stop):当SCL=1时,SDA由0向1跳变;
数据位:当SCL由0向1跳变时,由发送方控制SDA,此时SDA为有效数据,不可随意改变SDA;
当SCL保持为0时,SDA上的数据可随意改变;
地址位:定义同数据位,但只由Master发给Slave;
应答位(ACK):当发送方传送完8位时,发送方释放SDA,由接收方控制SDA,且SDA=0;
否应答位(NACK):当发送方传送完8位时,发送方释放SDA,由接收方控制SDA,且SDA=1。
当数据为单字节传送时,格式为:
开始位,8位地址位(含1位读写位),应答,8位数据,应答,停止位。
2. 配置I2C总线
- 定义I2C引脚:
- I2C总线由两条线组成:SCL(时钟线)和SDA(数据线)。你需要在51单片机上选择合适的引脚作为这两条线。
- 初始化I2C接口:
- 如果51单片机具有硬件I2C模块,配置寄存器以设置SCL和SDA的功能。大多数51单片机没有硬件I2C模块,因此需要通过软件实现。
- 软件实现通常涉及到使用定时器产生时钟信号,并在特定时序下控制数据线的状态。
- I2C通信的基本步骤:
- 开始条件:主设备拉低SDA线,同时保持SCL线为高电平。
- 发送数据:将数据位在SDA线上发送,时钟信号由SCL线控制。
- 接收数据:从设备在SDA线上发送数据,主设备提供时钟信号。
- 停止条件:主设备将SDA线拉高,同时保持SCL线为高电平。
3. 51单片机上I2C的简单应用示例
假设我们使用的是8051单片机和一个常见的I2C EEPROM芯片(如24LC256)。以下是一个简单的I2C写操作示例:
- 初始化I2C:
#define SCL P1_0 // 假设SCL连接到P1.0
#define SDA P1_1 // 假设SDA连接到P1.1
void I2C_Init() {
SCL = 1; // 初始化SCL为高
SDA = 1; // 初始化SDA为高
}
- 发送I2C开始条件:
void I2C_Start() {
SDA = 1; // 确保SDA为高
SCL = 1; // 确保SCL为高
SDA = 0; // 拉低SDA,产生开始条件
SCL = 0; // 拉低SCL
}
- 发送字节数据:
void I2C_SendByte(unsigned char data) {
for (int i = 0; i < 8; i++) {
if (data & 0x80) {
SDA = 1; // 发送1
} else {
SDA = 0; // 发送0
}
SCL = 1; // 产生时钟信号
SCL = 0;
data <<= 1; // 处理下一个数据位
}
}
- 发送I2C停止条件:
void I2C_Stop() {
SDA = 0; // 确保SDA为低
SCL = 1; // 拉高SCL
SDA = 1; // 拉高SDA,产生停止条件
}
- 写数据到EEPROM:
void I2C_WriteEEPROM(unsigned char address, unsigned char data) {
I2C_Start();
I2C_SendByte(0xA0); // EEPROM设备地址,假设写操作
I2C_SendByte(address); // 写入地址
I2C_SendByte(data); // 写入数据
I2C_Stop();
}
说明
- I2C_Start:产生一个I2C开始条件。
- I2C_SendByte:发送一个字节的数据,SDA线上的数据会在SCL线的时钟信号下发送。
- I2C_Stop:产生一个I2C停止条件。
- I2C_WriteEEPROM:执行写操作,包括发送设备地址、地址和数据字节。