STM32外设 - 0.96寸OLED显示屏

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

❤欢迎关注我的知乎:对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
GNDGND
3.3VVCC

3.2 SPI通信连接

若采用SPI通信方式,连接方式如下:

STM32引脚OLED引脚
PA5(SCK)SCK
PA7(MOSI)MOSI
PA4(CS)CS
PB0(DC)DC
PB1(RST)RST
GNDGND
3.3VVCC

四、软件编程(以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)在硬件连接和软件编程上的差异。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值