找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

51单片机初学之I2C通讯协议详解及用LED灯观察实验

查看数: 3112 | 评论数: 9 | 收藏 6
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2025-12-8 20:16

正文摘要:

通讯协议是干什么用的?它是各设备包括单片机以及各种外设之间用于传输数据的人为规则。前面的12864屏,我们采用的是一次传输一个字节8位二进制数的方式来传输数据的,这种传输方式的极其明显的缺点是占用的单片机的 ...

回复

ID:60178 发表于 2026-4-11 09:49
我经过研究发现,IIC用软件模拟,分别写启动程序,停止程序,再写移位和位与屏蔽取高一位判断就1还是0,然后把它等于到SDA上,发送程序,再ACK应答程序。用时在组装起来。硬件这些程序已经是寄存器命令,一字节数据放入BUF发送。好多通讯由软件模拟变为硬件,写程序就简单
你可以看IIC文字很难理解,不过直接看视频IIC软件手写过程,就通了
#ifndef __IIC_H
#define __IIC_H

#include "config.h"

// ===================== 引脚定义 =======================
sbit SCL = P1^0;   // 时钟线
sbit SDA = P1^1;   // 数据线

// ===================== 函数声明 =======================
void IIC_Init(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Send_Byte(unsigned char txd);
unsigned char IIC_Read_Byte(unsigned char ack);
bit IIC_Wait_Ack(void);
void IIC_Ack(void);
void IIC_NAck(void);

#endif
// ==============================
// 2. IIC起始信号
// ==============================
void IIC_Start(void)
{
    SDA = 1;   // 确保SDA高
    SCL = 1;   // 时钟高
    delay_us(5);
   
    SDA = 0;   // 时钟高电平时,SDA从高变低 = 起始信号
    delay_us(4);
   
    SCL = 0;   // 拉低时钟,准备发送数据
}// ==============================
// 3. IIC停止信号
// ==============================
void IIC_Stop(void)
{
    SDA = 0;   // 确保SDA低
    SCL = 1;   // 时钟高
    delay_us(5);
   
    SDA = 1;   // 时钟高时,SDA从低变高 = 停止信号
    delay_us(4);
}
// ==============================
// 4. 发送一个字节(8位)
// ==============================
void IIC_Send_Byte(unsigned char txd)
{
    unsigned char t;
   
    for(t=0;t<8;t++)  // 循环8次,发8位
    {
        SCL = 0;           // 时钟拉低,才能改变SDA
        delay_us(2);
        
        if((txd & 0x80)>>7)  // 取最高位
            SDA = 1;
        else
            SDA = 0;
        
        txd <<= 1;        // 左移一位
        delay_us(2);
        
        SCL = 1;          // 时钟拉高,从机采样数据
        delay_us(2);
    }
   
    SCL = 0;  // 8位发完,拉低时钟
    delay_us(2);// ==============================
// 5. 等待从机应答(ACK)
// ==============================
bit IIC_Wait_Ack(void)
{
    unsigned char ucErrTime = 0;
   
    SDA = 1; delay_us(1);  // 主机释放SDA
    SCL = 1; delay_us(1);  // 时钟拉高
   
    while(SDA)  // 读取SDA:低=应答,高=不应答
    {
        ucErrTime++;
        if(ucErrTime>250)
        {
            IIC_Stop();
            return 1; // 失败
        }
    }
   
    SCL = 0;  // 时钟拉低
    return 0; // 成功
}

}// ==============================
// 6. 主机产生应答 ACK
// ==============================
void IIC_Ack(void)
{
    SCL = 0;
    SDA = 0;   // 应答:SDA=0
    delay_us(2);
    SCL = 1;
    delay_us(2);
    SCL = 0;
}
// ==============================
// 8. 读取一个字节
// ==============================
unsigned char IIC_Read_Byte(unsigned char ack)
{
    unsigned char i,receive = 0;
   
    for(i=0;i<8;i++)
    {
        SCL = 0;
        delay_us(2);
        SCL = 1;  // 时钟拉高,读取数据
        
        receive <<= 1;
        if(SDA) receive++;
        
        delay_us(1);
    }
   
    if(!ack)
        IIC_NAck();  // 最后一个字节发NACK
    else
        IIC_Ack();   // 继续读发ACK
   
    return receive;
}
START → 发送设备地址 → 等待ACK → 发送寄存器地址 → ACK → 发送数据 → ACK → STOP

START → 设备地址 → ACK → 寄存器地址 → ACK →
START → 设备地址+1 → ACK → 读取数据 → NACK → STOP
五、必须记住的 5 条规则
SCL 高电平时,SDA 不能变
SCL 高电平时,SDA 下降沿 = START
SCL 高电平时,SDA 上升沿 = STOP
数据高位先发
每发 1 个字节必须等应答
六、这个代码能直接驱动哪些设备?
✅ OLED 显示屏
✅ 24C02 EEPROM
✅ MPU6050
✅ SHT30 / SHT20
✅ HMC5883
✅ 所有 IIC 设备

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的奖励!

查看全部评分

ID:1169534 发表于 2026-4-9 22:59
很给力啊!
ID:912238 发表于 2026-2-2 19:52
讲解非常的细致,谢谢楼主 加油 努力
ID:1164872 发表于 2025-12-12 21:11
来学习学习
ID:530727 发表于 2025-12-12 09:10
讲解非常的细致,看其他资料都没弄太明白
ID:530727 发表于 2025-12-12 09:08
讲的明白。
ID:266429 发表于 2025-12-9 20:35
任何串行通讯协议,其原理其实极其简单,就一条:通讯双方事先协商好,用不同的变化组合来表达不同的意思。
剩下的,就只是规则了:谁主谁从、什么样的动作组合表示开始、什么样的动作组合表示结束、什么样的动作表示开始传递数据、什么样的动作组合表示放上去了一位数据、什么样的动作表示可以读取数据了、什么样的动作表示这一位数据是1或是0、什么样的动作表示反馈信号、传输方向怎么确定、是从高位到低位还是从低位到高位进行传输、哪些数据是命令类数据哪些数据才是本次要传送的目标内容、要不要对接收到的数据进行正确性校验、对错误数据怎么处理,等等。
你在学习任何通讯协议时,要弄清楚的就是这些规则,万变不离其宗,这些规则没多少道理可讲,设计者就是这样规定的,我们该做的就是个死记。如果你看不惯或者觉得不够合理,可以,你自己想怎么设计就怎么设计,然后当然你也可以申请专利,至于能不能得到推广?要不你自娱自乐吧。
关于动作组合,实在是乏善可陈,就三个要素:电位、时间、传输数据线。
ID:266429 发表于 2025-12-9 17:16
dyx811 发表于 2025-12-9 12:32
IIC让我迷惑了好久,这里终于悟到了IIC通讯的真理,感谢楼主的分享!讲解非常的细致入微,是我学习的指路明 ...

谢了,你们的肯定,就是我的动力。
ID:34149 发表于 2025-12-9 12:32
IIC让我迷惑了好久,这里终于悟到了IIC通讯的真理,感谢楼主的分享!讲解非常的细致入微,是我学习的指路明灯,向您致敬!

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表