【已验证】STM32驱动OLED(SSD1306)显示字符
·
本文介绍如何使用STM32F103C8T6(蓝板)通过软件模拟IIC协议驱动0.96英寸OLED(驱动芯片SSD1306),这个小屏幕相信每一个朋友在大学生活里都不会错过,也是很多课设毕设显示需求的首选,我一向喜欢直接干,咱们也不说那些原理啥的,直接站在前人的肩膀优化,进而形成自己的框架。
1. 硬件连接
| OLED引脚 | STM32引脚 |
|---|---|
| VCC | 3.3V |
| GND | GND |
| SCL | PB6 |
| SDA | PB7 |
可根据实际修改引脚,只需在代码中对应修改即可。
2. 驱动架构
代码分为三个文件:
-
oled.h:引脚定义、函数声明 -
oled_font.h:存放所有字库数据(6x8 ASCII、8x16 ASCII、16x16汉字) -
oled.c:IIC模拟、OLED初始化、显示函数实现
这种结构将字库与驱动分离,便于维护和扩充汉字。
3. 关键代码实现
3.1 引脚定义与IIC宏
// oled.h #define OLED_SCL_PORT GPIOB #define OLED_SCL_PIN GPIO_PIN_6 #define OLED_SDA_PORT GPIOB #define OLED_SDA_PIN GPIO_PIN_7 #define OLED_SCL_H HAL_GPIO_WritePin(OLED_SCL_PORT, OLED_SCL_PIN, GPIO_PIN_SET) #define OLED_SCL_L HAL_GPIO_WritePin(OLED_SCL_PORT, OLED_SCL_PIN, GPIO_PIN_RESET) #define OLED_SDA_H HAL_GPIO_WritePin(OLED_SDA_PORT, OLED_SDA_PIN, GPIO_PIN_SET) #define OLED_SDA_L HAL_GPIO_WritePin(OLED_SDA_PORT, OLED_SDA_PIN, GPIO_PIN_RESET)
3.2 软件IIC核心函数
// oled.c
static void IIC_Start(void)
{
OLED_SDA_H; OLED_SCL_H;
delay_us(5);
OLED_SDA_L;
delay_us(5);
OLED_SCL_L;
}
static void IIC_Stop(void)
{
OLED_SCL_L; OLED_SDA_L;
delay_us(5);
OLED_SCL_H;
delay_us(5);
OLED_SDA_H;
}
static void IIC_SendByte(uint8_t byte)
{
for(uint8_t i=0; i<8; i++) {
if(byte & 0x80) OLED_SDA_H; else OLED_SDA_L;
byte <<= 1;
delay_us(2);
OLED_SCL_H; delay_us(2);
OLED_SCL_L; delay_us(2);
}
}
static void OLED_WriteCmd(uint8_t cmd)
{
IIC_Start();
IIC_SendByte(0x78); // 写地址
IIC_WaitAck();
IIC_SendByte(0x00); // 命令模式
IIC_WaitAck();
IIC_SendByte(cmd);
IIC_WaitAck();
IIC_Stop();
}
3.3 SSD1306初始化序列
void OLED_Init(void)
{
// 初始化GPIO(使能时钟,开漏输出)
OLED_WriteCmd(0xAE); // 关闭显示
OLED_WriteCmd(0x81); // 对比度设置
OLED_WriteCmd(0xFF);
OLED_WriteCmd(0xA4); // 正常显示
OLED_WriteCmd(0xA6); // 正显(0亮1灭)
OLED_WriteCmd(0x20); // 寻址模式
OLED_WriteCmd(0x10); // 页寻址模式
OLED_WriteCmd(0xB0); // 起始页0
OLED_WriteCmd(0x00); // 起始列低4位
OLED_WriteCmd(0x10); // 起始列高4位
OLED_WriteCmd(0x40); // 起始行
OLED_WriteCmd(0xA1); // 列重映射(SEG0->列127)
OLED_WriteCmd(0xA8); // 多路复用比
OLED_WriteCmd(0x3F);
OLED_WriteCmd(0xC8); // COM扫描方向(反向)
OLED_WriteCmd(0xD3); // 显示偏移
OLED_WriteCmd(0x00);
OLED_WriteCmd(0xDA); // COM引脚配置
OLED_WriteCmd(0x12);
OLED_WriteCmd(0xD9); // 预充电周期
OLED_WriteCmd(0x22);
OLED_WriteCmd(0xDB); // VCOMH电压
OLED_WriteCmd(0x20);
OLED_WriteCmd(0x8D); // 电荷泵
OLED_WriteCmd(0x14);
OLED_WriteCmd(0xAF); // 开启显示
}
3.4 显示字符
// 6x8 ASCII显示
void OLED_ShowChar_6x8(uint8_t x, uint8_t y, uint8_t ch)
{
uint8_t c = ch - 32;
OLED_SetPos(x, y);
for(uint8_t i=0; i<6; i++)
OLED_WriteData(F6x8[c][i]);
}
// 8x16 ASCII显示
void OLED_ShowChar_8x16(uint8_t x, uint8_t y, uint8_t ch)
{
uint8_t c = ch - 32;
OLED_SetPos(x, y);
for(uint8_t i=0; i<8; i++)
OLED_WriteData(F8X16[c*16 + i]);
OLED_SetPos(x, y+1);
for(uint8_t i=0; i<8; i++)
OLED_WriteData(F8X16[c*16 + i + 8]);
}
3.5 显示汉字(16x16)
void OLED_ShowChinese(uint8_t x, uint8_t y, uint8_t index)
{
uint16_t addr = index * 32; // 每个汉字32字节
OLED_SetPos(x, y);
for(uint8_t i=0; i<16; i++)
OLED_WriteData(F16x16[addr + i]);
OLED_SetPos(x, y+1);
for(uint8_t i=0; i<16; i++)
OLED_WriteData(F16x16[addr + 16 + i]);
}
5. 字库说明
-
6x8 ASCII:共95个字符,每个6字节,适合显示简单英文。
-
8x16 ASCII:共95个字符,每个16字节,高度为16,可显示更清晰的英文。
-
16x16汉字:用户可自行添加汉字,每个汉字32字节(列行式逆向输出)。示例中内置了“野火电子”四个汉字,可根据需要扩充。
字库数据存放在独立的头文件 oled_font.h 中,便于维护和替换。
6. 效果展示

通过网盘分享的文件:STM32_OLED_SoftIIC.zip
链接: https://pan.baidu.com/s/1CdxPxJS3hajggX4NcLUoxQ?pwd=rxnz 提取码: rxnz
--来自百度网盘超级会员v8的分享
更多推荐


所有评论(0)