1. 项目概述
在嵌入式开发中,OLED显示屏因其体积小、功耗低、显示清晰等优点被广泛应用。本文将详细介绍如何在STM32F103平台上使用HAL库驱动OLED显示屏,并实现6x8小字体的显示功能。
2. 硬件准备与连接
2.1 所需硬件
- STM32F103开发板
- 0.96寸OLED显示屏(SSD1306驱动芯片)
- 杜邦线若干
2.2 硬件连接
OLED显示屏通常支持I2C和SPI两种通信方式,本文采用I2C通信方式。连接方式如下:
| OLED引脚 | STM32引脚 |
|---|---|
| VCC | 3.3V |
| GND | GND |
| SCL | PB6 |
| SDA | PB7 |
注意:不同型号的OLED屏可能有不同的引脚定义,请务必参考具体型号的数据手册。
3. 软件实现
3.1 工程配置
首先需要在STM32CubeMX中配置I2C外设:
- 打开I2C1外设
- 配置PB6为I2C1_SCL,PB7为I2C1_SDA
- 设置I2C时钟频率为400kHz(快速模式)
- 生成代码
3.2 OLED驱动实现
3.2.1 寄存器写入函数
c复制HAL_StatusTypeDef OLED_WriteReg(uint8_t RegAddress, uint8_t Data)
{
return HAL_I2C_Mem_Write(
&hi2c1, // I2C句柄
OLED_ADDRESS, // OLED从机地址(0x78)
RegAddress, // 寄存器地址
OLED_REG_ADDR_LEN, // 寄存器地址长度(1字节)
&Data, // 要写入的数据
1, // 数据长度
100 // 超时时间(ms)
);
}
这个函数封装了HAL库的I2C写操作,简化了OLED寄存器的配置过程。
3.2.2 OLED初始化
c复制void OLED_HD_Init(void)
{
OLED_WriteReg(0x00,0xAE); // 关闭显示
OLED_WriteReg(0x00,0xD5); // 设置显示时钟分频比/振荡器频率
OLED_WriteReg(0x00,0x80);
OLED_WriteReg(0x00,0xA8); // 设置多路复用率
OLED_WriteReg(0x00,0x3F);
// 更多初始化命令...
OLED_WriteReg(0x00,0xAF); // 开启显示
OLED_Clear(); // 清屏
}
初始化过程需要按照SSD1306数据手册的要求,依次配置各种参数。
3.3 显示功能实现
3.3.1 设置光标位置
c复制void OLED_SetCursor(uint8_t Y, uint8_t X)
{
OLED_WriteReg(0x00,0xB0 | Y); // 设置Y位置
OLED_WriteReg(0x00,0x10 | ((X & 0xF0) >> 4)); // 设置X位置高4位
OLED_WriteReg(0x00,0x00 | (X & 0x0F)); // 设置X位置低4位
}
OLED屏幕被划分为8页(Page),每页8行。Y参数指定页号(0-7),X参数指定列号(0-127)。
3.3.2 显示6x8小字体
c复制void OLED_ShowChar_6_8(uint8_t Line, uint8_t Column, char Char)
{
uint8_t i;
// 设置光标位置
OLED_SetCursor((Line - 1), (Column - 1) * 6);
// 写入6x8字库数据
for (i = 0; i < 6; i++)
{
OLED_WriteReg(0x40, OLED_F6x8[Char - ' '][i]);
}
}
6x8字体每个字符占用6列宽度,相比传统的8x16字体可以显示更多内容。
3.3.3 显示字符串
c复制void OLED_ShowString_6_8(uint8_t Line, uint8_t Column, char *String)
{
uint8_t i;
for (i = 0; String[i] != '\0'; i++)
{
OLED_ShowChar_6_8(Line, Column + i, String[i]);
}
}
4. 性能优化
4.1 显示帧率
通过优化代码结构和使用硬件I2C,本实现可以达到14fps以上的刷新率。主要优化点包括:
- 使用HAL库的硬件I2C,避免软件模拟的延迟
- 减少不必要的屏幕清空操作
- 只更新需要改变的内容区域
4.2 内存占用
6x8字体相比8x16字体可以节省大量存储空间:
- 6x8字体:每个字符6字节
- 8x16字体:每个字符16字节
5. 常见问题与解决方法
5.1 屏幕无显示
- 检查硬件连接是否正确
- 确认I2C地址设置正确(通常为0x78或0x7A)
- 检查初始化序列是否完整
5.2 显示内容错乱
- 确认字库数据与显示函数匹配
- 检查屏幕分辨率设置(128x64)
- 确保每次更新显示前正确设置了光标位置
5.3 I2C通信失败
- 检查I2C总线是否有上拉电阻(通常需要4.7kΩ)
- 确认I2C时钟频率设置合理
- 使用逻辑分析仪检查I2C波形
6. 扩展功能
6.1 图形绘制
可以在现有基础上扩展绘制直线、矩形、圆形等基本图形的功能。
6.2 多级菜单系统
结合按键输入,可以实现基于OLED的菜单界面。
6.3 动画效果
利用OLED的高刷新率特性,可以实现简单的动画效果。
7. 实际应用示例
c复制int main(void)
{
HAL_Init();
SystemClock_Config();
MX_I2C1_Init();
OLED_HD_Init();
int16_t GY = 0, GZ = 0;
while (1)
{
OLED_ShowString_6_8(1,1," helloworld");
OLED_ShowString_6_8(2,1," good nb ");
HAL_Delay(100);
OLED_ShowSignedNum(3, 8, GY++, 5);
OLED_ShowSignedNum(4, 8, GZ++, 5);
}
}
这个示例展示了如何在OLED上显示静态字符串和动态变化的数字。
8. 注意事项
- OLED屏幕长时间显示静态内容可能导致烧屏,建议定期刷新或使用屏幕保护功能
- I2C总线长度不宜过长,否则可能导致通信失败
- 在恶劣电磁环境下,建议降低I2C时钟频率提高稳定性
- 使用6x8小字体时,要注意字符间距和可读性的平衡
9. 移植指南
将本驱动移植到其他平台时需要注意:
- 修改I2C底层驱动函数
- 根据具体OLED型号调整初始化序列
- 检查目标平台的存储空间是否足够存放字库
10. 总结
本文详细介绍了STM32F103使用HAL库驱动OLED显示屏的实现方法,重点讲解了6x8小字体的显示优化。通过硬件I2C和合理的代码结构,实现了较高的刷新率。这套驱动可以广泛应用于各种需要小型显示的嵌入式项目中。