云计算百科
云计算领域专业知识百科平台

解码内部集成电路(IIC)与OLED屏

内部集成电路(IIC/I2C)

图片04

基本概念

  • 英文全称Inter Integrated Circuit,简称IIC或I2C,是半双工同步串行通信接口协议
  • 1982年由飞利浦公司(现恩智浦半导体)设计推出
  • 设计初衷:为微控制器(MCU)与外围芯片提供简洁、可靠、低成本的通信方案,简化硬件设计和系统集成

图片01

引脚说明

图片02

  • 仅需两根引脚即可通信,硬件设计简洁:
    • 数据线(SDA,Serial Data):传输实际数据信息
    • 时钟线(SCL,Serial Clock):同步数据传输的时序控制
  • 所有支持IIC接口的外围设备(传感器、存储器等)可直接挂载在两根总线上
  • 支持多机通信架构:
    • 主从结构:单一主设备控制多个从设备
    • 多主结构:多个主设备协同工作
  • 核心机制:通过地址识别和仲裁机制实现设备间有序通信

总线结构

图片03

  • 采用开漏输出结构,可实现多设备双向通信与总线仲裁,避免电平冲突
  • 连接方式:所有外围器件的SCL和SDA均挂载在主控芯片提供的IIC总线上,形成共享信号通道
  • 空闲状态:上拉电阻将SCL和SDA均拉至高电平,总线处于待命状态,随时响应起始条件

线与逻辑

  • 多设备共享同一总线,某设备输出低电平时总线被拉低
  • 仅当所有设备释放总线(输出高阻态),上拉电阻才将总线恢复高电平
  • 核心作用:是IIC多主设备通信的基础,实现总线冲突检测与仲裁,保证数据传输有序性,简化硬件设计、降低系统成本

仲裁过程

当两个或多个主设备同时尝试发起通信时,仲裁过程如下:

  • ‌同时启动‌:假设主设备A和主设备B同时检测到总线空闲,并开始发送各自的起始条件和设备地址。
  • ‌逐位比对‌:在每一个时钟周期(SCL为高电平时),两个设备会同时在SDA线上输出一位数据,并立即采样SDA线的实际电平。
  • ‌仲裁失败判定‌:‌如果一个设备试图发送逻辑“1”(即释放SDA,让上拉电阻拉高),但采样到的总线电平为逻辑“0”,则说明有另一个设备正在发送逻辑“0”并成功拉低了总线。此时,试图发送“1”的设备立即判定为仲裁失败。‌‌12
  • ‌失败方退出‌:仲裁失败的设备会立即停止驱动SCL和SDA总线,转为监听模式,不再发送任何时钟或数据,以避免干扰胜出方的通信。‌1
  • ‌胜出方继续‌:仲裁成功的设备会继续完成其完整的通信过程(发送地址、读写数据、停止条件等),整个过程对胜出方来说是透明且无中断的。‌1
  • ‌失败方重试‌:仲裁失败的设备在检测到总线再次变为空闲后,可以重新尝试发起通信。

通信速率

  • 支持多种速率,适配不同场景:
    • 标准速率:100KHZ(满足多数基本控制和配置需求)
    • 快速速率:400KHZ(适用于高性能外围器件的高速应用场景)
  • 通信机制:半双工,同一时间仅能执行接收或发送操作,无法双向同时传输
  • 适用场景:侧重控制指令传输(设备控制、传感器读取、配置管理),不适合大规模数据交换

通信过程与时序分析

通信流程

  • 主机生成开始信号
  • 主机发送从设备地址(7位或10位)+ 读写控制位(bit0=0写操作,bit0=1读操作)
  • 从设备识别地址后应答,主机开始传输或接收数据
  • 数据传输完成后,主机生成停止信号,通信结束

图片03

空闲状态

图片05

  • SCL时钟线和SDA数据线均为高电平,由IIC总线的上拉电阻拉高

开始条件

图片06

  • SCL处于高电平期间,将SDA数据线的电平拉低,标志通信开始

传输数据

图片07

  • 时序同步方式:IIC以时钟脉冲的电平进行同步(区别于SPI的边沿同步)
  • 数据稳定性要求:
    • SCL低电平期间:SDA可切换电平(准备下一位数据)
    • SCL高电平期间:SDA必须保持稳定(确保数据可靠读取)
  • 传输规则:以字节为单位传输,MSB(高位)在前,需持续8个时钟脉冲

应答条件

图片08

  • 时序位置:字节传输8个时钟周期后,第9个时钟脉冲期间
  • 应答标志:接收方将SDA拉低表示应答(ACK),保持高电平表示非应答(NACK)
  • 控制方式:应答位可通过软件使能或禁止

停止条件

图片09

  • SCL处于高电平期间,将SDA数据线的电平拉高,标志通信结束

器件地址

图片010

  • 常规格式:7位二进制数(数据手册明确标注)
  • 扩展格式:10位二进制数(需占用两个字节传输)
  • 地址类型:包括设备自身地址和广播呼叫地址(广播呼叫地址检测可通过软件使能/禁止)
  • 作用:实现多设备识别,确保数据准确传输到目标设备

时序模拟

  • 硬件限制:MCU内部硬件IIC接口数量有限(如部分MCU仅3个)
  • 两种实现方式:
    • 硬件IIC:使用专用IIC引脚,需复用引脚功能并配置初始化
    • IO口模拟IIC:通过普通IO口模拟IIC时序,不受硬件接口数量限制,可移植性更高

代码(此处为了理解时序,引脚配置为推挽,实际要配置为开漏)

/* Private define ————————————————————*/
// 引脚定义 自行选择要用的引脚 此处不做定义
#define IIC_SDA_PIN
#define IIC_SDA_GPIO_PORT
#define IIC_SDA_GPIO_CLK

#define IIC_SCL_PIN
#define IIC_SCL_GPIO_PORT
#define IIC_SCL_GPIO_CLK

// IIC引脚电平操作
#define IIC_SDA_LOW() GPIO_ResetBits(IIC_SDA_GPIO_PORT, IIC_SDA_PIN)
#define IIC_SDA_HIGH() GPIO_SetBits(IIC_SDA_GPIO_PORT, IIC_SDA_PIN)

#define IIC_SCL_LOW() GPIO_ResetBits(IIC_SCL_GPIO_PORT, IIC_SCL_PIN)
#define IIC_SCL_HIGH() GPIO_SetBits(IIC_SCL_GPIO_PORT, IIC_SCL_PIN)

#define IIC_SDA_READ() GPIO_ReadInputDataBit(IIC_SDA_GPIO_PORT, IIC_SDA_PIN)

/* Private functions ———————————————————*/
/**
* @brief IIC底层GPIO初始化
* @param None
* @retval None
*/

void IIC_LowLevel_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

// 使能GPIO时钟
RCC_AHB1PeriphClockCmd(IIC_SDA_GPIO_CLK | IIC_SCL_GPIO_CLK , ENABLE);

// IIC引脚配置(推挽输出+上拉,符合IIC总线规范)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉

// SDA引脚配置
GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;
GPIO_Init(IIC_SDA_GPIO_PORT, &GPIO_InitStructure);

// SCL引脚配置
GPIO_InitStructure.GPIO_Pin = IIC_SCL_PIN;
GPIO_Init(IIC_SCL_GPIO_PORT, &GPIO_InitStructure);

// 总线空闲状态:SDA/SCL均为高
IIC_SDA_HIGH();
IIC_SCL_HIGH();
delay_us(10); // 初始延时
}

/**
* @brief IIC SDA引脚模式切换(输出/输入)
* @param Mode: 引脚模式(GPIO_Mode_OUT/GPIO_Mode_IN)
* @retval None
*/

void IIC_SDAPinModeSet(GPIOMode_TypeDef Mode)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(IIC_SDA_GPIO_CLK, ENABLE);

GPIO_InitStructure.GPIO_Mode = Mode;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉

GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;
GPIO_Init(IIC_SDA_GPIO_PORT, &GPIO_InitStructure);
}

/**
* @brief IIC起始信号(SCL高时,SDA从高拉低)
* @param None
* @retval None
*/

void IIC_Start(void)
{
IIC_SDAPinModeSet(GPIO_Mode_OUT);

IIC_SDA_HIGH();
IIC_SCL_HIGH();
delay_us(5); // 时序延时,保证总线稳定

IIC_SDA_LOW();
delay_us(5);

IIC_SCL_LOW();
}

/**
* @brief IIC停止信号(SCL高时,SDA从低拉高)
* @param None
* @retval None
*/

void IIC_Stop(void)
{
IIC_SDAPinModeSet(GPIO_Mode_OUT);

IIC_SCL_LOW();
IIC_SDA_LOW();
delay_us(5);

IIC_SCL_HIGH();
delay_us(5);

IIC_SDA_HIGH();
delay_us(5);
}

/**
* @brief IIC发送1字节数据(MSB先行)
* @param byte: 待发送字节
* @retval None
*/

void IIC_Send(uint8_t byte)
{
uint8_t cnt = 0;
IIC_SDAPinModeSet(GPIO_Mode_OUT);

for(cnt=0; cnt<8; cnt++)
{
IIC_SCL_LOW();
delay_us(2);

// 输出当前位(最高位先行)
if(byte & 0x80)
IIC_SDA_HIGH();
else
IIC_SDA_LOW();
delay_us(2);

byte <<= 1;

IIC_SCL_HIGH();
delay_us(2);
}

IIC_SCL_LOW();
delay_us(2);
}

/**
* @brief 检测IIC从机应答
* @param None
* @retval true: 应答成功 false: 无应答
*/

bool IIC_IsACK(void)
{
bool status = false;

IIC_SDAPinModeSet(GPIO_Mode_IN); // 切换为输入模式读应答
delay_us(2);

IIC_SCL_LOW();
delay_us(2);

IIC_SCL_HIGH();
delay_us(2);

// 从机应答:SDA拉低
if(!IIC_SDA_READ())
status = true;
else
status = false;

IIC_SCL_LOW();
delay_us(2);
return status;
}

/**
* @brief 主机发送应答/非应答
* @param ack: 0=应答 1=非应答
* @retval None
*/

void IIC_SendAck(uint8_t ack)
{
IIC_SDAPinModeSet(GPIO_Mode_OUT);

IIC_SCL_LOW();
delay_us(2);

if(ack)
IIC_SDA_HIGH(); // 非应答
else
IIC_SDA_LOW(); // 应答
delay_us(2);

IIC_SCL_HIGH();
delay_us(2);

IIC_SCL_LOW();
delay_us(2);
}

/**
* @brief IIC读取1字节数据(MSB先行)
* @param None
* @retval 读取到的字节
*/

uint8_t IIC_Read(void)
{
uint8_t cnt = 0;
uint8_t data = 0;

IIC_SDAPinModeSet(GPIO_Mode_IN);

for(cnt=0; cnt<8; cnt++)
{
IIC_SCL_LOW();
delay_us(2);

IIC_SCL_HIGH();
delay_us(2);

data <<= 1;
data |= IIC_SDA_READ(); // 读取当前位
delay_us(1);
}

IIC_SCL_LOW();
delay_us(2);
return data;
}

OLED屏的原理与应用

基本概念

  • 英文全称Organic Light Emitting Diode(有机发光二极管)
  • 核心特性:自发光(无需背光)、对比度高、厚度薄、视角广、反应速度快、可挠曲、使用温度范围广、构造及制程简单
  • 0.96寸OLED屏关键参数:
    • 分辨率:128*64
    • 颜色选项:黄蓝(1/4黄光+3/4蓝光,固定区域)、纯白(黑底白字)、纯蓝(黑底蓝字)
    • 接口方式:5种(6800并行、8080并行、3线SPI、4线SPI、IIC),通过屏上BS0~BS2引脚配置
    • 模块类型:七针SPI/IIC兼容模块、四针IIC模块

驱动芯片

  • 主流芯片:SSD1306(本屏所用)

  • 核心特点:内置升压功能,无需额外设计升压电路(也支持外部升压,参考数据手册)

  • 存储结构:每页128字节,共8页,刚好匹配128**64点阵*

    image

  • 与SSD1106的区别:

    • SSD1106每页132字节,共8页
    • 移植注意:用0.96寸OLED移植1.3寸(SSD1106)程序时,需将显示地址向右偏移2,否则右侧4个像素点显示异常

器件地址

图片011

  • IIC从设备地址:默认0x78(7位地址)
  • 地址构成:011110 + SA0 + R/W#
    • SA0位:地址扩展位,可选择0111100(0x78)或0111101(0x79),由D/C#引脚控制
    • R/W#位:操作模式选择,R/W#=1为读模式,R/W#=0为写模式
  • 硬件要求:SDA和SCL引脚需连接上拉电阻

硬件接线

图片012

  • 核心引脚:VCC(电源)、GND(地)、SCL(IIC时钟线)、SDA(IIC数据线)
  • 接线原则:按模块引脚定义与MCU的IIC引脚(或模拟IIC的IO口)对应连接,确保电源电压匹配(参考模块数据手册)

点击此处获取移植代码 效果

1

取模操作

取模软件

需使用专用字模软件生成汉字、图片的点阵数据,存入字模库(oledfont.h)

图片取模参数

图片013

汉字取模参数

图片014

赞(0)
未经允许不得转载:网硕互联帮助中心 » 解码内部集成电路(IIC)与OLED屏
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!