STM32F4X OLED使用

OLED简介

OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。
OLED跟LCD不同,LCD需要背光才能点亮,而OLED不需要背光,因为它是自发光。因为技术的原因,目前OLED不能做得很大,目前常见的OLED尺寸有0.96、1.3、1.54和2.42寸。本节实验将会使用2.42寸、分辨率为128*64的OLED做实验。

OLED使用

OLED驱动芯片

通常OLED内部都会一块OLED的驱动芯片,驱动芯片的作用是接收用户发送的数据,将数据进行管理,最后将数据显示到OLED上。常见的OLED驱动芯片有SSD1306、SSD1309等,操作OLED实际就是操作OLED的驱动芯片。本次实验用的驱动芯片是SSD1309。

SSD1309引脚

引脚作用
CS片选信号,低电平有效
RES复位信号
D/C数据、命令引脚。低电平为写命令、高电平为写数据
R/WMCU接口的读写控制输入引脚
EMCU接口输入
D7~D0并行传输接口
BS2~BS0OLED通信接口选择

SSD1309通信协议

SSD1309支持并行通信和串行通信,具体的通信方法选择是通过BS2~BS0引脚进行选择。

BS[2:0]接口
0004线SPI
0013线SPI
010I2C
1108-bit 8080接口
1008-bit 6800接口

4线SPI模式

将BS[2:0]设置为000即可进入4线SPI模式,在4线SPI模式下,需要7根通信引脚

引脚作用
RES复位信号
D/C写数据、写命令
CS片选
D0用作SCL
D1用作SDA
VCC电源
GND地线

在这里插入图片描述

  1. 先将CS信号拉低,代表选中OLED,开始通信
  2. 根据用户发送的数据还是命令,选择D/C信号的电平,低电平为发送命令,高电平为发送数据
  3. 将需要发送的数据(8bit)按照高位在前的方式,在时钟信号的上升沿发送给OLED
  4. 数据发送完之后,再将CS拉高。

3线SPI模式

将BS[2:0]设置为001即可进入3线SPI模式,在4线SPI模式下,需要6根通信引脚

引脚作用
RES复位信号
CS片选
D0用作SCL
D1用作SDA
VCC电源
GND地线

在这里插入图片描述
3线SPI模式跟4线SPI模式非常相似,主要区别是3线SPI模式下没有D/C信号线,D/C信号是以数据的形式发送出去。

  1. 先将CS信号拉低,代表选中OLED,开始通信
  2. 在需要发送的数据前添加一个D/C选择位,0为发送命令,1为发送数据
  3. 将需要发送的数据(9bit)按照高位在前的方式,在时钟信号的上升沿发送给OLED
  4. 数据发送完之后,再将CS拉高。

I2C模式

将BS[2:0]设置为010即可进入I2C模式,在I2C模式下,需要5根通信引脚

引脚作用
RES复位信号
SCL时钟线
SDA数据线
VCC电源
GND地线
OLED地址确认

凡是涉及到I2C通信,从机设备都要确定好地址,SSD1309的地址设置如下

A6A5A4A3A2A1A0R/W
011110SA01/0

SA0为地址选择信号,由D/C信号线决定,也就是说一个I2C总线上可以接2个OLED设备。

在这里插入图片描述

  1. 主机发送起始信号,告诉从机开始通信
  2. 主机等待从机ACK信号
  3. 主机发送控制字节
  4. 主机等待从机ACK信号
  5. 主机发送数据
  6. 主机等待从机ACK信号
  7. 主机发送停止信号,结束通信。

使用I2C通信需要注意控制字节的配置字。控制字节的高6位是D/C信号,bit为0代表发送命令,bit为1代表发送数据。
控制字节的高7位是设置是否需要连续发送显示数据,其目的是让OLED快速刷屏。我们通过上图的通信协议知道,当我们每次需要发送一个字节时,都需要开启一个完整的I2C通信,如果需要大量数据刷屏时就很浪费时间,当Co为0且D/C为1时,则开启连续发送数据模式,只需启动一个I2C通信,就可以连续发送数据,直到停止。

8080接口

将BS[2:0]设置为110即可进入8080模式,在8080模式下,需要15根通信引脚

引脚作用
RES复位信号
CS片选
D/C写命令、写数据信号
RD读数据信号,低电平有效
WR写数据,低电平有效
D7~D0并行数据口
VCC电源
GND地线
OLED 8080写模式

在这里插入图片描述

  • 将CS信号拉低,开始通信
  • 将WR信号拉低,同时将RD信号拉高,代表写模式
  • 根据是写命令还是写数据选择D/C电平信号
  • 将数据通过D7~D0引脚发送到OLED
  • 将CS信号拉高,WR信号拉高,结束通信
OLED 8080读模式

在这里插入图片描述

  • 将CS信号拉低,开始通信
  • 将RD信号拉低,同时将WR信号拉高,代表读模式
  • 根据是写命令还是写数据选择D/C电平信号
  • 读出D7~D0上的数据
  • 将CS信号拉高,RD信号拉高,结束通信

6800接口

将BS[2:0]设置为100即可进入8080模式,在6800模式下,需要15根通信引脚

引脚作用
RES复位信号
CS片选
D/C写命令、写数据信号
RW读写信号
D7~D0并行数据口
E使能信号
VCC电源
GND地线

在这里插入图片描述

SSD1309显示原理

SSD1309显存大小

OLED本身是没有存储显示数据的功能,这个功能是由SSD1309提供,SSD1309内部提供了一块显存区域,其分辨率为128 * 64,这个分辨率也就是OLED的分辨率。意思是这块OLED最多可以显示128 * 64位的数据,也就是1024个字节,长度最大为128,宽度最大为64。
在这里插入图片描述

SSD1309显存分布

SSD1309内部的显存大致如下分布。
在这里插入图片描述
SSD1309内部的显存可以划分成128 * 64个格子,每个格子代表一个bit。SSD1309又将这些格子进一步划分,按照8列为一组,分成了8页,每页大小为128 * 8个格子,也就是128字节为一页。
在这里插入图片描述

SSD1039数据显示

我们拿其中一页作为例子,来说一下在SSD1309内部数据是怎样存放的。我们需要知道的是在SSD1309内部,所有的数据都是按照列来存放,假设我们在PAGE0的(0,0)这个位置写入一个数据0xAC,那么其存储格式如下。最低位在前,高位在后。
在这里插入图片描述

MCU操作SSD1309显存方法

针对SSD1309的显存存储结构,MCU每次修改数据的时候都需要将SSD1309的显存数据读出来,确保旧的数据跟新的数据没有冲突,但是这就有一个问题,每次修改数据的数据都需要读显存数据,这样就很浪费时间。所以在实际应用中,一般都会在MCU中定义一个128*64bit大小的二维数组,这个数组可以看做是SSD1309的外部显存,每次需要更新数据时,都会更新这个外部显存,最后再通过命令把整个显存数据刷新到SSD1309内部。

OLED取模

由于SSD1309内部是没有字库的,所以我们需要自己制作字库文件,这样OLED才能显示图片、字符等。字库的制作软件PCtoLCD2002,软件大家可以自行到网上进行下载。

字符取模

我们需要制作常用的ASCII码字符,需要制作的字符如下,第一个ASCII码为空格

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
  • 设置软件为字符取模模式

在这里插入图片描述

  • 点击选项,进入设置模式,按照以下方法进行取模设置

在这里插入图片描述

  • 以生成8x16字符为例

在这里插入图片描述
在这里插入图片描述
在生成字符前先选择字符的高度和宽度,然后将需要生成的字符复制到输入框内,点击生成字模,最后点击保存字模,生成后的字模就会保存到文件中。

图片取模

例程位图图片下载

  • 设置图片大小
    首先点击上面的网址,下载图片。下载完成后打开windows的画图软件,修改图片分辨率为128 * 64。
    在这里插入图片描述
    修改完成后将图片另存为BMP格式的图片。
  • 设置软件为图片取模模式
    在这里插入图片描述
  • 设置取模模式
    在这里插入图片描述
  • 生成图片字模
    在这里插入图片描述
    将制作好的BMP图片加载到软件中,点击生成字模,然后点击保存字模。

STM32F4X OLED例程

本节例程中用到的OLED是128 * 64分辨率的OLED,通信协议是4线SPI协议。
在这里插入图片描述
在这里插入图片描述

OLED关键函数讲解

数据传输函数


void oled_write_byte(unsigned char byte,unsigned char type)
{
	unsigned char i;
	GPIO_ResetBits(OLED_CS_PIN_PORT,OLED_CS_PIN); // CS 拉低
	
	if(OLED_WRITE_CMD == type)   
		GPIO_ResetBits(OLED_DC_PIN_PORT,OLED_DC_PIN); // 写命令 拉低DC
	else
		GPIO_SetBits(OLED_DC_PIN_PORT,OLED_DC_PIN); // 写数据 拉高DC
	
	
	for(i = 0;i < 8;i++)  // 传输数据
	{
		GPIO_ResetBits(OLED_SCL_PIN_PORT,OLED_SCL_PIN); // 拉低SCL
		
		if(byte & 0x80)
			GPIO_SetBits(OLED_SDA_PIN_PORT,OLED_SDA_PIN);
		else
			GPIO_ResetBits(OLED_SDA_PIN_PORT,OLED_SDA_PIN);
		
		GPIO_SetBits(OLED_SCL_PIN_PORT,OLED_SCL_PIN); // 拉高SCL
		byte <<= 1; // 数据左移一位
	}
	GPIO_SetBits(OLED_CS_PIN_PORT,OLED_CS_PIN); // 拉高CS
	GPIO_SetBits(OLED_DC_PIN_PORT,OLED_DC_PIN); // 拉高DC
}

在开始传输数据前,要先把CS信号拉低,代表选中OLED,然后根据是写命令还是写数据,改变D/C信号电平,在SCL的上升沿的时候把数据按照高位在前,低位在后依次发送给OLED,最后拉高CS和D/C信号。
程序的实现都是按照数据手册的时序要求进行设计。
在这里插入图片描述

画点函数

void oled_drawpoint(unsigned char x,unsigned char y,unsigned char t)
{
    u8 i,m,n;
    i=y/8; // 判断是第几页
    m=y%8; // 判断是第几位
    n=1<<m;

    if(t){OLED_GRAM[x][i]|=n;} // 如果是1就直接写数据
    else
    { // 如果是0,就清0
        OLED_GRAM[x][i]=~OLED_GRAM[x][i];
        OLED_GRAM[x][i]|=n;
        OLED_GRAM[x][i]=~OLED_GRAM[x][i];
    }
}

在往GRAM写数据前,先判断该点位于GRAM的页数,然后再判断该点是第几个bit,最后再根据是否需要点亮该bit进行写1或者清0操作。

写GRAM

static  unsigned char OLED_GRAM[128][8];
//更新显存到OLED
void oled_refresh(void)
{
    u8 i,n;
    for(i=0;i<8;i++)
    {
       oled_write_byte(0xb0+i,OLED_WRITE_CMD); //设置页
       oled_write_byte(0x00,OLED_WRITE_CMD);   //设置低列起始地址
       oled_write_byte(0x10,OLED_WRITE_CMD);   //设置高列起始地址
       for(n=0;n<128;n++)
         oled_write_byte(OLED_GRAM[n][i],OLED_WRITE_DATA);
  }
}

程序会先定义一个128*8的二维数据,数据类型为unsigned char类型,也就是1024个字节,用户更新完数据后,再将这个GRAM刷新到SSD1309内部的GRAM中,从而实现了更新OLED的目的。

完整例程

由于例程过大,请在百度网盘下载
链接:https://pan.baidu.com/s/1ZjxPKjeIG1PyOVn7OHIjeQ
提取码:z59g

在这里插入图片描述

因本人水平有限,错误和疏漏之处在所难免,欢迎指正。

### 2.42寸 OLED 显示屏硬件接口与连接方式 对于2.42寸 OLED 显示屏,其通常支持多种硬件接口形式,例如 IIC (I²C) 和 SPI 接口。以下是针对该尺寸 OLED 的常见引脚定义及其连接方法: #### 引脚定义 常见的 2.42 寸 OLED 屏幕可能具有以下引脚配置(具体需参照屏幕制造商提供的规格书或原理图): - **GND**: 地线,用于提供电路的地电平。 - **VCC/VDD**: 电源输入端子,一般为 3.3V 或 5V,取决于设备的工作电压范围[^1]。 - **SCL/CLK/D0**: 对应于 IIC 协议的数据时钟信号;如果是 SPI,则表示时钟信号。 - **SDA/MOSI/D1**: 数据传输线路,在 IIC 中作为双向数据通道;在 SPI 下则负责主输出从输入操作。 - **RESET/RES**: 复位功能引脚,低电平时触发复位动作。 - **DC/A0**: 区分当前发送的信息是命令还是数据。 - **CS/SS**: 片选信号,当此引脚拉低时允许访问特定芯片。 如果采用的是更大的七针版本(如某些型号),还会有额外的 D/CX 及其他控制信号加入其中[^4]。 #### 连接教程 以 Arduino 平台为例,假设使用 SPI 方式驱动一块标准型号的 2.42 英寸 OLED 显示器,可以按照如下方式进行物理连线设置: | OLED Pin | Function | Connected To | |----------|----------------|--------------| | VCC | Power Supply | 5V | | GND | Ground | GND | | SCK/SCL | Serial Clock | Digital Pin X| | MOSI/SDA | Master Out Slave In |Digital Pin Y | | RES | Reset Signal | Digital Pin Z | | DC | Data/Command Select|Digital Pin W | | CS | Chip Select | Digital Pin Q | 注意这里的 `Pin X`, `Y` 等代表具体的微控制器上的实际可用GPIO编号位置[^3]。 另外值得注意的一点在于不同品牌之间即使标注相同名称也可能存在差异因此务必仔细阅读对应产品的技术手册确认无误后再实施焊接或者面包板测试过程[^2]. ```cpp #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); void setup() { if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { while(true); } } void loop() {} ``` 上述代码片段展示了如何初始化一个典型的基于 I2C 总线工作的图形库实例化对象并完成基本启动序列验证是否有错误发生的情况处理逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值