STM32驱动OLED屏幕全解析:从原理到温度显示实战(中) | 零基础入门STM32第五十四步

主题 内容 教学目的/扩展视频
OLED显示屏重点课程 电路原理,手册分析,驱动程序。初始化,清屏,ASCII字库,显示分区。调用显示函数。 做带有加入图形和汉字显示的RTC时钟界面。讲字库的设计原理。

师从洋桃电子,杜洋老师


文章目录

    • 一、OLED驱动架构设计
    • 二、关键函数解析(oled0561.c)
      • 2.1 初始化函数 OLED0561_Init
      • 2.2 显示控制函数
      • 2.3 清屏函数
    • 三、字符显示原理
      • 3.1 单字符显示函数
      • 3.2 字符串显示函数
    • 四、温度显示实战
      • 4.1 主程序实现
    • 五、高级功能扩展
      • 5.1 亮度调节
      • 5.2 图形显示优化
    • 六、常见问题排查
    • 七、相关资源
    • 总结与优化建议


▲ 回顾上期STM32驱动OLED屏幕全解析:从原理到温度显示实战(上) | 零基础入门STM32第五十三步


一、OLED驱动架构设计

OLED硬件
调用
依赖
基于
SH1106驱动芯片
STM32固件库
128x64像素矩阵
应用层 main.c
显示层 oled0561.c
I2C驱动层 i2c.c

二、关键函数解析(oled0561.c)

2.1 初始化函数 OLED0561_Init

void OLED0561_Init(void) {
    OLED_DISPLAY_OFF();      // 关闭显示
    OLED_DISPLAY_CLEAR();    // 清屏
    OLED_DISPLAY_ON();       // 开启显示
}
  • 执行流程
    1. 关闭显示避免干扰
    2. 清空显存防止残影
    3. 发送初始化指令序列
    4. 开启显示

2.2 显示控制函数

// 开启显示(发送28字节初始化指令)
void OLED_DISPLAY_ON(void) {
    u8 buf[28] = {0xAE, 0x00, 0x10, 0xD5, 0x80,...};
    I2C_SAND_BUFFER(OLED0561_ADD, COM, buf, 28);
}

// 关闭显示(发送3字节指令)
void OLED_DISPLAY_OFF(void) {
    u8 buf[3] = {0xAE, 0x8D, 0x10};
    I2C_SAND_BUFFER(OLED0561_ADD, COM, buf, 3);
}
  • 关键指令
    • 0xAE:关闭显示
    • 0xAF:开启显示
    • 0x81 0xFF:设置对比度最大值

2.3 清屏函数

void OLED_DISPLAY_CLEAR(void) {
    for(t=0xB0; t<0xB8; t++) {   // 遍历0~7页
        I2C_SAND_BYTE(..., t);    // 设置页地址
        I2C_SAND_BYTE(..., 0x10); // 列地址高4位
        I2C_SAND_BYTE(..., 0x00); // 列地址低4位
        for(j=0;j<132;j++) {      // 填充132列
            I2C_SAND_BYTE(..., 0x00); // 写入0x00熄灭像素
        }
    }
}
  • 显存结构:8页×128列,每列8像素(1字节)

三、字符显示原理

3.1 单字符显示函数

void OLED_DISPLAY_8x16(u8 x, u8 y, u16 w) {
    y += 2; // 列偏移补偿
    for(t=0; t<2; t++) {         // 每个字符占2页
        I2C_SAND_BYTE(..., 0xB0+x); // 设置页地址
        I2C_SAND_BYTE(..., y/16+0x10); // 列高4位
        I2C_SAND_BYTE(..., y%16);     // 列低4位
        for(j=0;j<8;j++) {           // 每页8列数据
            u8 data = ASCII_8x16[w*16 + c - 512];
            I2C_SAND_BYTE(..., data);
            c++;
        }
        x++; // 切换到下一页
    }
}
  • 字库设计
    • 8x16像素,纵向取模(低位在下)
    • ASCII码从0x20开始,索引需减512对齐

3.2 字符串显示函数

void OLED_DISPLAY_8x16_BUFFER(u8 row, u8 *str) {
    u8 r = 0;
    while(*str != '\0') {
        OLED_DISPLAY_8x16(row, r*8, *str++); // 字符间距8像素
        r++;
    }
}
  • 显示位置计算
    • row:行号(0~7)
    • r*8:列坐标(每个字符占8列)

四、温度显示实战

4.1 主程序实现

int main(void) {
    u8 buffer[3];
    OLED0561_Init(); 
    OLED_DISPLAY_8x16_BUFFER(0, "  Temp: ");

    while(1) {
        LM75A_GetTemp(buffer);
        
        // 显示符号位
        if(buffer[0]) OLED_DISPLAY_8x16(6, 7*8, '-');
        
        // 显示整数部分
        OLED_DISPLAY_8x16(6, 8*8, buffer[1]/10 + 0x30); // 十位
        OLED_DISPLAY_8x16(6, 9*8, buffer[1]%10 + 0x30); // 个位
        
        // 显示小数部分
        OLED_DISPLAY_8x16(6,11*8, buffer[2]/10 + 0x30);
        OLED_DISPLAY_8x16(6,12*8, buffer[2]%10 + 0x30);
    }
}
  • 数据转换技巧
    • +0x30:将数字转换为ASCII字符
    • 7*8:计算列位置(第7列)

五、高级功能扩展

5.1 亮度调节

void OLED_DISPLAY_LIT(u8 x) {
    I2C_SAND_BYTE(OLED0561_ADD, COM, 0x81); // 对比度指令
    I2C_SAND_BYTE(OLED0561_ADD, COM, x);    // 亮度值(0~255)
}
  • 亮度曲线:非线性调节,建议值50~200

5.2 图形显示优化

图形数据
取模软件处理
生成位图数组
分段写入显存
局部刷新降低功耗

六、常见问题排查

现象 排查步骤 解决方案
屏幕无显示 1. 检查VCC电压
2. 验证I2C地址
确保发送0xAE/0xAF指令
字符显示错位 1. 检查列偏移补偿
2. 验证字库索引
调整y+2偏移量
显示残影 1. 增加清屏操作
2. 检查对比度设置
清屏后延时100ms
I2C通信失败 1. 抓取波形
2. 检查上拉电阻
使用4.7kΩ上拉电阻

七、相关资源

[1] 洋桃电子B站课程-STM32入门100步
[2] STM32F103xx官方数据手册
[3] STM32F103X8-B数据手册(中文)
[4] STM32F103固件函数库用户手册(中文)
[5] OLED12864显示屏数据手册
[6] 温度值OLED屏显示程序
[7] OLED屏驱动程序分析.pptx


总结与优化建议

  1. 驱动层优化
    • 使用DMA传输提升刷新速度
    • 实现局部刷新功能降低功耗
  2. 应用层扩展
    • 添加中文字库支持
    • 实现滑动菜单效果
  3. 关键注意点
    // 必须的延时配置
    #define INIT_DELAY 100 // 初始化后延时100ms
    #define REFRESH_RATE 30 // 刷新率30Hz
    

通过深入分析SH1106驱动芯片的指令集,结合STM32的I2C外设特性,可以构建稳定高效的OLED显示系统。建议使用逻辑分析仪验证关键时序,并配合STM32CubeMX生成初始化代码框架。


技术讨论(请在评论区留言~)

下期预告:下一期将探讨OLED屏驱动程序分析3重点课程,欢迎持续关注!

点击查阅往期【STM32专栏】文章

版权声明:本文采用[CC BY-NC-SA 4.0]协议,转载请注明来源
实测开发版:洋桃1号开发版(基于STM32F103C8T6)
更新日志

  • v1.0 初始版本(2025-03-08)

你可能感兴趣的:(STM32入门教程(100步),stm32,嵌入式硬件,单片机,驱动开发,物联网)