✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进
❤欢迎关注我的知乎:对error视而不见
代码获取、问题探讨及文章转载可私信。
☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。
🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇
一、引言
在STM32的应用开发中,常常需要将系统的状态信息、测量数据等直观地展示给用户,0.96寸OLED显示屏便是一个非常合适的选择。它具有体积小、功耗低、显示效果好等优点,能够满足很多嵌入式系统的显示需求。本文将详细介绍如何使用STM32驱动0.96寸OLED显示屏,包括硬件连接、软件编程等方面。
二、0.96寸OLED显示屏简介
2.1 基本特性
- 显示尺寸:0.96寸,对角线长度约为24.4mm。
- 分辨率:常见的分辨率为128×64,能够清晰地显示文字、图标和简单的图形。
- 驱动芯片:一般采用SSD1306作为驱动芯片,该芯片支持I2C和SPI两种通信协议。
- 显示颜色:通常为单色(白色),具有较高的对比度。
2.2 通信协议
- I2C协议:使用两根信号线(SCL和SDA)进行通信,具有连线简单、占用引脚少的优点,适合对引脚资源要求较高的应用场景。
- SPI协议:使用四根信号线(SCK、MOSI、MISO、CS)进行通信,通信速度较快,适合对数据传输速度要求较高的应用场景。
三、硬件连接
3.1 I2C通信连接
假设使用STM32F103C8T6开发板,采用I2C通信方式连接0.96寸OLED显示屏,连接方式如下:
STM32引脚 | OLED引脚 |
---|---|
PB6(SCL) | SCL |
PB7(SDA) | SDA |
GND | GND |
3.3V | VCC |
3.2 SPI通信连接
若采用SPI通信方式,连接方式如下:
STM32引脚 | OLED引脚 |
---|---|
PA5(SCK) | SCK |
PA7(MOSI) | MOSI |
PA4(CS) | CS |
PB0(DC) | DC |
PB1(RST) | RST |
GND | GND |
3.3V | VCC |
四、软件编程(以I2C通信为例)
4.1 I2C初始化
#include "stm32f10x.h"
#define OLED_ADDRESS 0x78 // OLED的I2C地址
// I2C初始化函数
void I2C_Configuration(void)
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 使能I2C1和GPIOB时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// 配置I2C1的SCL和SDA引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 配置I2C1
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_Init(I2C1, &I2C_InitStructure);
// 使能I2C1
I2C_Cmd(I2C1, ENABLE);
}
// I2C发送一个字节数据
void I2C_SendByte(uint8_t data)
{
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, data);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
}
4.2 OLED初始化
// OLED初始化函数
void OLED_Init(void)
{
I2C_Configuration();
// 复位OLED
I2C_SendByte(0x00); // 发送命令模式
I2C_SendByte(0xAE); // 关闭显示
I2C_SendByte(0xD5); // 设置显示时钟分频比/振荡器频率
I2C_SendByte(0x80);
I2C_SendByte(0xA8); // 设置多路复用率
I2C_SendByte(0x3F);
I2C_SendByte(0xD3); // 设置显示偏移
I2C_SendByte(0x00);
I2C_SendByte(0x40); // 设置显示开始行
I2C_SendByte(0x8D); // 电荷泵设置
I2C_SendByte(0x14);
I2C_SendByte(0x20); // 设置内存寻址模式
I2C_SendByte(0x00);
I2C_SendByte(0xA1); // 设置段重映射
I2C_SendByte(0xC8); // 设置COM输出扫描方向
I2C_SendByte(0xDA); // 设置COM引脚硬件配置
I2C_SendByte(0x12);
I2C_SendByte(0x81); // 设置对比度控制
I2C_SendByte(0xCF);
I2C_SendByte(0xD9); // 设置预充电周期
I2C_SendByte(0xF1);
I2C_SendByte(0xDB); // 设置VCOMH取消选择级别
I2C_SendByte(0x40);
I2C_SendByte(0xA4); // 全局显示开启
I2C_SendByte(0xA6); // 设置正常显示
I2C_SendByte(0xAF); // 开启显示
}
4.3 OLED显示字符
// 显示一个字符
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr)
{
uint8_t c = chr - ' ';
if (x > 128 - 8) return;
if (y > 64 - 8) return;
I2C_SendByte(0x00); // 发送命令模式
I2C_SendByte(0xb0 + y);
I2C_SendByte(((x & 0xf0) >> 4) | 0x10);
I2C_SendByte((x & 0x0f) | 0x01);
for (uint8_t i = 0; i < 8; i++)
{
I2C_SendByte(0x40); // 发送数据模式
I2C_SendByte(font8x16[c * 16 + i]);
}
I2C_SendByte(0x00); // 发送命令模式
I2C_SendByte(0xb0 + y + 1);
I2C_SendByte(((x & 0xf0) >> 4) | 0x10);
I2C_SendByte((x & 0x0f) | 0x01);
for (uint8_t i = 0; i < 8; i++)
{
I2C_SendByte(0x40); // 发送数据模式
I2C_SendByte(font8x16[c * 16 + i + 8]);
}
}
// 显示字符串
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr)
{
while (*chr)
{
OLED_ShowChar(x, y, *chr);
x += 8;
if (x > 120)
{
x = 0;
y += 2;
}
chr++;
}
}
4.4 主函数
// 字体表(8x16)
const uint8_t font8x16[] = {
// 字体数据
};
int main(void)
{
OLED_Init();
while (1)
{
OLED_ShowString(0, 0, "Hello, World!");
}
}
4.5 代码解释
- I2C初始化:
I2C_Configuration
函数用于初始化STM32的I2C接口,包括使能时钟、配置引脚和I2C参数等。I2C_SendByte
函数用于通过I2C接口发送一个字节的数据。 - OLED初始化:
OLED_Init
函数通过发送一系列的命令来初始化OLED显示屏,包括设置显示模式、对比度、扫描方向等。 - 显示字符和字符串:
OLED_ShowChar
函数用于在指定位置显示一个字符,OLED_ShowString
函数用于在指定位置显示一个字符串。 - 主函数:在主函数中,首先调用
OLED_Init
函数初始化OLED显示屏,然后在循环中调用OLED_ShowString
函数显示字符串 “Hello, World!”。
五、总结
通过以上的硬件连接和软件编程,我们可以使用STM32驱动0.96寸OLED显示屏,实现字符和字符串的显示。在实际应用中,还可以进一步扩展功能,如显示图形、图片等。同时,需要注意不同的通信协议(I2C或SPI)在硬件连接和软件编程上的差异。