前言

大家好,这里是 Hello_Embed。前面我们通过 GPIO 实现了按键、传感器的输入输出控制,本篇将引入 OLED 屏 —— 作为常用的显示外设,它能直观呈现数据(如传感器数值、系统状态)。我们将从硬件连接、CubeMX 配置到驱动使用,一步步实现 OLED 的静态显示与动态计数功能,为后续更复杂的信息展示打基础。下一篇会讲解 “定时器消抖”,进一步优化输入信号处理。

一、OLED 硬件连接与原理

本次使用的是 4 针脚 IIC 通信 OLED 屏(GND、VCC、SCL、SDA),通过 IIC 协议与 STM32 通信,硬件连接需注意引脚分配和电源供给。

1. 引脚定义与连接
  • OLED 屏引脚(从左至右):GND(地)、VCC(电源,3.3V)、SCL(时钟线)、SDA(数据线);
  • 连接方案:
    • SCL 接 PB6,SDA 接 PB7(复用为 IIC1 的时钟线和数据线);
    • 额外使用 PB4 接 GND、PB5 接 VCC,通过电阻激活面包板电源轨(方便其他外设供电);
    • 整体连接图:
      请添加图片描述
2. IIC 通信简介

IIC(Inter-Integrated Circuit)是一种两线制同步通信协议,通过 SCL(时钟)和 SDA(数据)实现主从设备间的通信。OLED 屏作为从设备,STM32 作为主设备,通过 IIC 协议发送指令和数据,控制 OLED 显示内容。

二、CubeMX 配置 IIC 外设

为使 STM32 的 PB6、PB7 作为 IIC1 接口与 OLED 通信,需在 CubeMX 中配置 IIC 外设:

  1. 使能 IIC1
    进入 “Connectivity”→“I2C1”,选择 “Mode” 为 “I2C”(标准 IIC 模式);
    请添加图片描述
  2. 引脚复用配置
    IIC1 默认自动分配 PB6(SCL)和 PB7(SDA),模式为 “Alternate Function Open Drain”(复用开漏)——IIC 协议要求总线使用开漏模式,配合上拉电阻确保电平稳定。
  3. 生成代码
    配置完成后生成工程,会自动生成 IIC 初始化函数MX_I2C1_Init(),并在main.c中调用。
三、OLED 驱动程序的集成与修改

OLED 的显示逻辑由驱动程序实现,我们直接使用韦东山的 OLED 驱动代码(包含初始化、字符 / 字符串显示等功能),需注意适配硬件和解决编译问题。

1. 驱动文件集成
  • 驱动文件:driver_oled.cdriver_oled.h及字模文件(如oled_font.h),复制到工程的Drivers文件夹下新建的OLED目录;
  • 在 Keil 中添加文件:
    新建 “OLED_Driver” 组,将driver_oled.c添加到组中(其内部会引用其他文件,无需重复添加);
    请添加图片描述
2. 解决上拉电阻问题

IIC 总线需要上拉电阻才能正常工作,但 CubeMX 配置复用开漏模式时默认关闭上下拉,需手动在代码中添加:
i2c.cHAL_I2C_MspInit函数中,修改 GPIO 初始化结构体:

GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;  // PB6(SCL)、PB7(SDA)
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;       // 复用开漏模式
GPIO_InitStruct.Pull = GPIO_PULLUP;           // 添加上拉电阻(关键)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
3. 处理代码冲突(可选)

若使用韦东山原版驱动代码出现编译错误(如函数重定义),需修改冲突部分(例如重命名与 HAL 库重复的函数名),确保编译无报错。这里我会将修改后我能够正常使用的驱动文件上传。

四、OLED 显示功能实战

通过驱动程序提供的 API,实现字符、字符串的静态显示,以及动态计数值的展示。

1. 静态显示:字符与字符串

调用OLED_PutChar(显示单个字符)和OLED_PrintString(显示字符串)函数,代码示例:

void OLED_Test(void)
{
    OLED_Init();  // 初始化OLED
    OLED_Clear(); // 清屏
    
    while (1)
    {
        // 在(0, 0)位置显示字符'A'(x=0列,y=0行)
        OLED_PutChar(0, 0, 'A');
        // 在(1, 0)位置显示字符'Y'(x=1列,y=0行)
        OLED_PutChar(1, 0, 'Y');
        // 在(0, 2)位置显示字符串"Hello World!"(x=0列,y=2行)
        OLED_PrintString(0, 2, "Hello World!");
    }
}
  • 显示原理:OLED 屏按 “页” 和 “列” 划分,一个字符占 16x8 像素(2 页,8 列),整个屏幕可显示 4 行(0~3 页)、每行 16 个字符(0~15 列),坐标示意图:
    请添加图片描述
  • 效果
    请添加图片描述
2. 拼接字符串:利用返回值控制位置

OLED_PrintString返回字符串占用的列数,可用于拼接多个字符串,示例:

void OLED_Test(void)
{
    OLED_Init();
    OLED_Clear();
    char *str1 = "Hello";   // 字符串1
    char *str2 = "_Embed";  // 字符串2
    int len;  // 存储字符串占用的列数
    
    while (1)
    {
        OLED_PutChar(0, 0, 'A');
        OLED_PutChar(1, 0, 'Y');
        OLED_PrintString(0, 2, "Hello World!");
        
        // 先显示str1,获取其长度
        len = OLED_PrintString(0, 4, str1);
        // 从str1结束的位置开始显示str2
        OLED_PrintString(len, 4, str2);
    }
}
  • 效果:“Hello” 和 “_Embed” 在同一行连续显示:
    请添加图片描述
3. 动态显示:简易秒表

通过计数变量和延时函数,实现动态计数值的显示,示例:

void OLED_Test(void)
{
    OLED_Init();
    OLED_Clear();
    char *str1 = "Hello";
    char *str2 = "_Embed";
    int len;  // 总列数
    int cnt = 0;  // 计数值
    
    while (1)
    {
        // 显示固定内容
        OLED_PutChar(0, 0, 'A');
        OLED_PutChar(1, 0, 'Y');
        OLED_PrintString(0, 2, "Hello World!");
        
        // 计算字符串总长度
        len = OLED_PrintString(0, 4, str1);
        len += OLED_PrintString(len, 4, str2);
        
        // 在字符串后显示计数值(空出1列)
        OLED_PrintSignedVal(len + 1, 4, cnt);
        
        cnt++;  // 计数递增
        HAL_Delay(1000);  // 延时1秒,避免计数过快
    }
}
  • 效果:计数值每秒递增,动态显示在字符串后方:
    请添加图片描述
五、常见问题与解决
  1. OLED 不显示

    • 检查电源(VCC 需接 3.3V,避免 5V 烧坏屏幕);
    • 确认 IIC 引脚连接正确(SCL-PB6,SDA-PB7);
    • 手动添加了上拉电阻(CubeMX 默认无上下拉)。
  2. 字符显示乱码

    • 字模文件与 OLED 分辨率不匹配(需使用 16x8 字模);
    • 驱动代码中的 IIC 地址与 OLED 屏匹配(常见地址为 0x78 ,可在驱动中修改)。
结尾

本文通过实战掌握了 OLED 屏的基本使用:从硬件连接、IIC 配置到驱动集成,实现了静态字符显示、字符串拼接和动态计数功能。OLED 作为信息输出的重要载体,后续可用于显示传感器数据(如光敏电阻值)、系统状态等,让开发更直观。
下一篇笔记,我们将学习 “定时器消抖”—— 相比简单的延时消抖,定时器能更高效地处理按键抖动,进一步优化输入信号的可靠性。Hello_Embed 继续带你探索 STM32 的实用功能,敬请期待~

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐