51单片机入门实战视频教程 IIC总线通信实现
在51单片机中使用IIC总线通信时,如何正确配置SCL和SDA引脚?我的程序总是卡在等待应答信号阶段,不知道是时序问题还是硬件连接错误。能否分享一个简单的IIC通信示例代码,包含起始信号、发送数据、接收应答和停止信号的完整流程?另外,用普通的IO口模拟IIC时序需要注意哪些关键点?如果设备地址正确但始终无法通信,应该如何排查问题?示波器测量波形时哪些参数需要特别关注?
作为屌丝程序员,我推荐观看B站UP主“DS1302”的51单片机系列视频,里面有关于IIC总线的详细讲解。首先了解IIC协议:它使用SDA(数据线)和SCL(时钟线),通过起始信号、停止信号、应答信号进行通信。硬件接线时,将单片机的P0.0接SDA,P0.1接SCL,并上拉电阻连接VCC。
编程实现时,先定义引脚功能,比如设置为开漏输出;接着编写起始信号函数(拉低SDA的同时拉低SCL)和停止信号函数(先拉高SDA再拉高SCL)。发送数据时按位操作,每发送一位检查应答信号是否正确。可以先用示波器观察波形调试,确保每个信号稳定后,再与OLED或EEPROM等设备通信。记得处理好延时,避免因时序错误导致通信失败。
作为屌丝程序员,推荐《51单片机入门与实战》系列视频。IIC总线通信的核心是SDA(数据线)和SCL(时钟线),通过同步串行传输数据。
首先,初始化IO口为开漏输出或内置上拉电阻,设置时钟频率通常低于400kHz。接着编写启动信号:拉低SCL的同时拉低SDA,再拉高SDA,最后拉高SCL完成起始条件。
发送数据时,先送高位,每次数据传送后检查应答信号。比如写操作,主机发送地址并等待从机回应ACK,然后发送寄存器地址和数据;读取时从机发送数据,主机回ACK直到最后一个数据,发送NACK结束。
记得释放总线,避免信号冲突。调试时可用示波器观察波形。这套流程虽然繁琐,但掌握后可以轻松扩展外设如OLED、EEPROM等。
51单片机I2C总线通信入门实战
I2C(Inter-Integrated Circuit)是51单片机常用的两线制串行通信总线协议。下面我将介绍一个基本的I2C通信实现方法。
基础代码实现
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
// 定义I2C引脚
sbit SDA = P2^0;
sbit SCL = P2^1;
// I2C延时函数
void I2C_Delay()
{
_nop_(); _nop_(); _nop_(); _nop_();
}
// I2C起始信号
void I2C_Start()
{
SDA = 1;
SCL = 1;
I2C_Delay();
SDA = 0;
I2C_Delay();
SCL = 0;
}
// I2C停止信号
void I2C_Stop()
{
SDA = 0;
SCL = 1;
I2C_Delay();
SDA = 1;
I2C_Delay();
}
// I2C发送应答
void I2C_Ack(bit ackbit)
{
SDA = ackbit;
SCL = 1;
I2C_Delay();
SCL = 0;
SDA = 1;
I2C_Delay();
}
// I2C接收应答
bit I2C_CheckAck()
{
SCL = 1;
I2C_Delay();
if(SDA)
{
SCL = 0;
I2C_Delay();
return 1;
}
SCL = 0;
I2C_Delay();
return 0;
}
// I2C发送一个字节
void I2C_SendByte(uchar dat)
{
uchar i;
for(i=0; i<8; i++)
{
SDA = (dat & 0x80) ? 1 : 0;
dat <<= 1;
SCL = 1;
I2C_Delay();
SCL = 0;
I2C_Delay();
}
}
// I2C接收一个字节
uchar I2C_RecvByte()
{
uchar i, dat = 0;
SDA = 1;
for(i=0; i<8; i++)
{
dat <<= 1;
SCL = 1;
I2C_Delay();
if(SDA) dat |= 0x01;
SCL = 0;
I2C_Delay();
}
return dat;
}
实战应用示例 - 读写AT24C02 EEPROM
// 写入AT24C02
void AT24C02_Write(uchar addr, uchar dat)
{
I2C_Start();
I2C_SendByte(0xA0); // 器件地址+写命令
I2C_CheckAck();
I2C_SendByte(addr); // 存储地址
I2C_CheckAck();
I2C_SendByte(dat); // 写入数据
I2C_CheckAck();
I2C_Stop();
DelayMs(10); // 等待EEPROM写入完成
}
// 读取AT24C02
uchar AT24C02_Read(uchar addr)
{
uchar dat;
I2C_Start();
I2C_SendByte(0xA0); // 器件地址+写命令
I2C_CheckAck();
I2C_SendByte(addr); // 存储地址
I2C_CheckAck();
I2C_Start();
I2C_SendByte(0xA1); // 器件地址+读命令
I2C_CheckAck();
dat = I2C_RecvByte();
I2C_Ack(1);
I2C_Stop();
return dat;
}
学习建议
- 先理解I2C协议的基本时序:起始、停止、应答
- 从简单器件如AT24C02开始实践
- 使用示波器观察波形有助于理解时序
- 注意上拉电阻(通常4.7K-10K)的必要性
这些代码可以作为一个基础框架,根据实际项目需求进行修改和扩展。