STM32学习日记——OLED模块
写于8月24日凌晨,该文章仅供自己学习参考,欢迎大家指点交流
文章目录
- STM32学习日记——OLED模块
- 1. 硬件驱动接口模式8080并口模式
- 2. OLED显存GDDRAM
- 3. 指令格式
- 3.1 基础指令 Fundamental Command Table
- 3.2 Scrolling Command 滚动设置
- 3.3 Addressing Setting Command Table 寻址方式设置
- 3.3.1 Set Lower Column Start Address for Page Addressing Mode为页面寻址模式设置低列起始地址
- 3.3.2 Set Higher Column Start Address forPage AddressingMode 为页面寻址设置高列起始地址
- 3.3.3 Set Memory Addressing Mode 设置内存寻址模式
- 3.3.4 Set Column Address设置列地址
- 3.3.5 Set Page Start Address for Page Addressing Mode为页面寻址模式设置页面开始地址
- 3.3.6 Set Page Start Address for Page Addressing Mode为页面寻址模式设置页面开始地址
- 4.OLED 模块的初始化过程
- 5.总结
- 5.总结
1. 硬件驱动接口模式8080并口模式
1.1 信号线
-
CS:OLED 片选信号。
-
WR:向 OLED 写入数据。
-
RD:从 OLED 读取数据。
-
D[7:0]:8 位双向数据线。
-
RST(RES):硬复位 OLED。
-
DC:命令/数据标志(0,读写命令;1,读写数据)。
1.2 时序图
1.2.1 写时序
模块的 8080 并口写的过程为:
-
先根据要写入的数据的类型,设置 DC 为高(数据)/低(命令),设置 WR 起始电平为高,然后拉低片选,选中 SSD1306
-
接着我们在整个读时序上保持RD 为高电平,然后拉低 WR 的电平准备写入数据,向数据线(D[7:0])上输入要写的信息
-
拉高 WR,这样得到一个 WR 的上升沿,在这个上升沿,使数据写入到 SSD1306 里面
1.2.2 读时序
模块的 8080 并口读的过程为:
- 先根据要写入的数据的类型,设置 DC 为高(数据)/低(命令),设置 RD 起始电平为高
- 然后拉低片选 CS 信号,选中 SSD1306,接着我们在整个读时序上保持 WR 为高电平
- 然后类似写时序,同样的,在 RD 的上升沿,使数据锁存到数据线(D[7:0])上;
2. OLED显存GDDRAM
GDDRAM全称Graphic Display Data RAM,为SSD1306内部的数据内存,SSD1306通过Common Driver驱动OLED显示,可以理解为OLED显示的图像跟随GDDRAM里的内容(当然也可以设置不跟随,用于刷新处理),下图为SSD1306驱动OLED显示屏的逻辑关系:
在上电初始化后,SSD1306默认设置为COM0驱动Row0,COM63驱动Row63(后续可以设置);COM驱动对应内部GDDRAM关系如下:
SSD1306 的显存总共为 128*64bit 大小,SSD1306 将这些显存分为了 8 页,不使用显存对应的行列的重映射,其对应关系如表 24.1.2.1 所示:
可以看出,SSD1306 的每页包含了 128 个字节,总共 8 页,这样刚好是 128*64 的点阵大小。当 GRAM 的写入模式为页模式时,需要设置低字节起始的列地址(0x00~ 0x0F)和高字节的起始列地址(0x10~0x1F),芯片手册中给出了写入 GRAM 与显示的对应关系,写入列地址在写完一字节后自动按列增长。
所以我们采用的办法是在 STM32F103 的内部建立一个虚拟的 OLED 的 GRAM(共128*8=1024 个字节),每次修改时,只修改 STM32F103 上的 GRAM(实际上就是 SRAM),在修改完成后一次性把 STM3F103 上的 GRAM写入到OLED 的 GRAM。当然这个方法也有坏处,一个对于那些 SRAM 很小的单片机(比如 51 系列)不太友好,另一个是每次都写入全屏,屏幕刷新率会变低。
总结如下:
- 显存GDDRAM大小为128*64;
- SSD1306通过Common Driver驱动OLED每一行的显示;
- 控制上,每8个COM组成一个Page,共有8个Page,即64行;
- 每一个COM中有128个Segment,即128列;
- 通过设置COM与Page的映射关系,可以改变OLED的行刷新方向;
- 通过设置SEG与Column的映射关系,可以改变OLED的列刷新方向;
- 在一个Page中,数据刷新总是从低SEG刷新到高SEG;在一个SEG中,数据的低位在上,高位在下,即在一个SEG中数据总是从低COM刷新到高COM。
至此,我们弄清楚了GDDRAM里数据和OLED显示的关系。
3. 指令格式
SSD1306 的命令比较多,这里我们仅介绍几个比较常用的命令
参考SSD1306参考手册可以查到全部的指令,先写指令,再写数据
3.1 基础指令 Fundamental Command Table
3.1.1 Set Contrast Control(设置对比度)
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
0x81 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 设置对比度 |
A[7:0] | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 | 对比度(0~255) 默认值为0x7F(127) |
这个命令首先发送命令字节0x81,然后再发送对比度数据。
实际上是设置OLED的驱动电流,对比度设置越大,驱动电流越大,显示效果就越亮。
3.1.2 Entire Display ON(OLED显示跟随GDDRAM)
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
0xA4/0xA5 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | X0 | 0xA4:OLED显示跟随GDDRAM 0xA5:OLED显示固定,不跟随GDDRAM 默认为0xA4 |
这个命令只需发送命令字节0xA4或0xA5,可以设置OLED的显示内容是否跟随GDDRAM内容变化
3.1.3 Set Normal/Inverse Display (设置反色)
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
0xA6/0xA7 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | X0 | 0xA6:正常显示,即GDDRAM中1表示显示,0表示不显 0xA7:反转显示,即GDDRAM中0表示显示,1表示不显 默认为0xA6 |
这个命令只需发送命令字节0xA6或0xA7,可以设置OLED的显示反色。
3.1.4 Set Display ON/OFF (开启/关闭显示)
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
0xAE/0xAF | 1 | 0 | 1 | 0 | 1 | 1 | 1 | X0 | 0xAE:关闭显示,进入睡眠模式 0xAF:开启显示 默认为0xAE |
这个命令只需发送命令字节0xAE或0xAF,可以设置OLED是否开启显示
3.2 Scrolling Command 滚动设置
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
0x26/0x27 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | X0 | 0x26, X[0]=0, 右水平滚动 0x27, X[0]=1, 左水平滚动 (水平滚动 1 列) |
A[7:0] | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | A[7:0] : 虚拟字节(设置为 00h) |
B[2:0] | * | * | * | * | * | B2 | B1 | B0 | 定义起始页地址 |
C[2:0] | * | * | * | * | * | C2 | C1 | C0 | 设置每个滚动步骤之间的时间间隔 帧频率术语 |
D[2:0] | * | * | * | * | * | D2 | D1 | D0 | 定义结束页地址D[2:0] 的值必须大于或等于至 B[2:0] |
E[7:0] | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 虚拟字节(设置为 00h) |
F[7:0] | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 虚拟字节(设置为 FFh) |
3.3 Addressing Setting Command Table 寻址方式设置
3.3.1 Set Lower Column Start Address for Page Addressing Mode为页面寻址模式设置低列起始地址
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
00~0F | 0 | 0 | 0 | 0 | X3 | X2 | X1 | X0 | 设置列起始地址的下半字节 使用 X[3:0] 注册页面寻址模式 作为数据位。初始显示线路寄存器为 RESET后重置为0000b。 |
这个命令设置在页寻址(Page Addressing)模式下列起始地址的低4位。
这个命令仅在页寻址模式下有效
3.3.2 Set Higher Column Start Address forPage AddressingMode 为页面寻址设置高列起始地址
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
10~1F | 0 | 0 | 0 | 1 | X3 | X2 | X1 | X0 | 使用 X[3:0] 为页面寻址模式设置列起始地址寄存器的较高半字节 作为数据位。初始显示行寄存器为 RESET 后重置为 0000b。 |
3.3.3 Set Memory Addressing Mode 设置内存寻址模式
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
0x20 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 设置内存寻址模式 |
A[1:0] | * | * | * | * | * | * | A1 | A0 | A[1:0] = 00b, 水平寻址模式 A[1:0] = 01b, 垂直寻址模式 A[1:0] = 10b, 页面寻址模式 (RESET) A[1:0] = 11b, 无效 |
这个命令首先发送0x20命令字节,然后发送寻址模式选择字节,各寻址模式如下:
页寻址模式:
水平/行寻址模式:
垂直/列寻址模式:
3.3.4 Set Column Address设置列地址
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
0x21 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 设置列起始地址和结束地址 此命令仅在行/列寻址模式下有效 |
A[6:0] | * | A6 | A5 | A4 | A3 | A2 | A1 | A0 | A[6:0]:列起始地址,范围:0-127d, (重置=0d) |
B[6:0] | * | B6 | B5 | B4 | B3 | B2 | B1 | B0 | B[6:0]:列结束地址,范围:0-127d, (重置 =127d) |
这个命令首先发送0x21命令字节,然后发送2个数据字节用于设定列的起始和结束地址。
3.3.5 Set Page Start Address for Page Addressing Mode为页面寻址模式设置页面开始地址
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
0x22 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 设置页面开始和结束地址 此命令仅适用于水平或垂直寻址模式。 |
A[2:0] | * | * | * | * | * | A2 | A1 | A0 | A[2:0] : 页面起始地址,范围: 0-7d, (重置 = 0d) |
B[2:0] | * | * | * | * | * | B2 | B1 | B0 | B[2:0]:页面结束地址,范围:0-7d, (复位 = 7d) |
这个命令用于设置页寻址模式下的页起始地址。结合命令4.3.1和4.3.2,可以设置页寻址模式下一页的数据寻址刷新,如下图设置起始页为Page2,起始列为3:
3.3.6 Set Page Start Address for Page Addressing Mode为页面寻址模式设置页面开始地址
指令/数据 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 指令作用 |
---|---|---|---|---|---|---|---|---|---|
B0~B7 | 1 | 0 | 1 | 1 | 0 | X2 | X1 | X0 | 设置 GDDRAM 页面起始地址 (PAGE0~PAGE7) 用于寻址模式使用 X[2:0]。 此命令仅适用于页面寻址模式 |
4.OLED 模块的初始化过程
- 设置STM32F103与OLED 模块相连接的IO
这一步,先将我们与 OLED 模块相连的 IO 口设置为输出,具体使用哪些 IO 口,这里需要根据连接电路以及 OLED 模块所设置的通讯模式来确定。这些将在硬件设计部分向大家介绍。
- 初始化OLED模块
其实这里就是上面的初始化框图的内容,通过对 OLED 相关寄存器的初始化,来启动 OLED的显示。为后续显示字符和数字做准备。
- 通过函数将字符和数字显示到OLED模块上。
这里就是通过我们设计的程序,将要显示的字符送到 OLED 模块就可以了,这些函数将在软件设计部分向大家介绍。
4.1 硬件连接
这里我用的是正点原子的战舰开发板与OLED屏幕
插入后查文档得出接口对应的GPIO接口
4.2 程序设计
4.2.1 ASCII 字符集内容
首先,用oledfont.h 头文件存储
/* 常用 ASCII 表
* 偏移量 32
* ASCII 字符集: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]
^_`abcdefghijklmnopqrstuvwxyz{|}~
* PC2LCD2002 取模方式设置:阴码+逐列式+顺向+C51 格式
* 总共:3 个字符集(12*12、16*16 和 24*24),用户可以自行新增其他分辨率的字符集。
* 每个字符所占用的字节数为:(size/8+((size%8)?1:0))*(size/2),其中 size:是字库生成时的点
* 阵大小(12/16/24...)
*/
/* 12*12 ASCII 字符集点阵 */
const unsigned char oled_asc2_1206[95][12]={ ...这里省略字符集库... };
/* 16*16 ASCII 字符集点阵 */
const unsigned char oled_asc2_1608[95][16]={ ...这里省略字符集库... };
/* 24*24 ASICII 字符集点阵 */
const unsigned char oled_asc2_2412[95][36]={ ...这里省略字符集库... };
该头文件中包含三个大小不同的 ASCII 字符集点阵,其中包括:1212 ASCII 字符集点阵、16 * 16 ASCII 字符集点阵、2424 ASICII 字符集点阵。每个字符集点阵都包含 95 个常用的 ASCII字符集 , 从空格符开始 ( 即 ASCII 码 表 编 号 的 32~127 对 应 的 字 符 ) ,分别
为:
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
4.2.2 oled.c 文件的驱动源码
oled.c 文件的驱动源码介绍
/**
* @brief 初始化OLED(SSD1306)
* @param 无
* @retval 无
*/
#define OLED_CMD 0 /* 写命令 */
#define OLED_DATA 1 /* 写数据 */
void oled_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOC_CLK_ENABLE(); /* 使能PORTC时钟 */
__HAL_RCC_GPIOD_CLK_ENABLE(); /* 使能PORTD时钟 */
__HAL_RCC_GPIOG_CLK_ENABLE(); /* 使能PORTG时钟 */
/* PC0 ~ 7 设置 */
gpio_init_struct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; /* 中速 */
HAL_GPIO_Init(GPIOC, &gpio_init_struct); /* PC0 ~ 7 设置 */
gpio_init_struct.Pin = GPIO_PIN_3|GPIO_PIN_6; /* PD3, PD6 设置 */
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; /* 中速 */
HAL_GPIO_Init(GPIOD, &gpio_init_struct); /* PD3, PD6 设置 */
gpio_init_struct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; /* 中速 */
HAL_GPIO_Init(GPIOG, &gpio_init_struct); /* WR/RD/RST引脚模式设置 */
OLED_WR(1);
OLED_RD(1);
OLED_CS(1);
OLED_RS(1);
OLED_RST(0);
delay_ms(100);
OLED_RST(1);
oled_wr_byte(0xAE, OLED_CMD); /* 关闭显示 */
oled_wr_byte(0xD5, OLED_CMD); /* 设置时钟分频因子,震荡频率 */
oled_wr_byte(80, OLED_CMD); /* [3:0],分频因子;[7:4],震荡频率 */
oled_wr_byte(0xA8, OLED_CMD); /* 设置驱动路数 */
oled_wr_byte(0X3F, OLED_CMD); /* 默认0X3F(1/64) */
oled_wr_byte(0xD3, OLED_CMD); /* 设置显示偏移 */
oled_wr_byte(0X00, OLED_CMD); /* 默认为0 */
oled_wr_byte(0x40, OLED_CMD); /* 设置显示开始行 [5:0],行数. */
oled_wr_byte(0x8D, OLED_CMD); /* 电荷泵设置 */
oled_wr_byte(0x14, OLED_CMD); /* bit2,开启/关闭 */
oled_wr_byte(0x20, OLED_CMD); /* 设置内存地址模式 */
oled_wr_byte(0x02, OLED_CMD); /* [1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10; */
oled_wr_byte(0xA1, OLED_CMD); /* 段重定义设置,bit0:0,0->0;1,0->127; */
oled_wr_byte(0xC8, OLED_CMD); /* 设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 */
oled_wr_byte(0xDA, OLED_CMD); /* 设置COM硬件引脚配置 */
oled_wr_byte(0x12, OLED_CMD); /* [5:4]配置 */
oled_wr_byte(0x81, OLED_CMD); /* 对比度设置 */
oled_wr_byte(0xEF, OLED_CMD); /* 1~255;默认0X7F (亮度设置,越大越亮) */
oled_wr_byte(0xD9, OLED_CMD); /* 设置预充电周期 */
oled_wr_byte(0xf1, OLED_CMD); /* [3:0],PHASE 1;[7:4],PHASE 2; */
oled_wr_byte(0xDB, OLED_CMD); /* 设置VCOMH 电压倍率 */
oled_wr_byte(0x30, OLED_CMD); /* [6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc; */
oled_wr_byte(0xA4, OLED_CMD); /* 全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) */
oled_wr_byte(0xA6, OLED_CMD); /* 设置显示方式;bit0:1,反相显示;0,正常显示 */
oled_wr_byte(0xAF, OLED_CMD); /* 开启显示 */
oled_clear();
}
该函数的结构比较简单,开始是对 GPIO 口的初始化,这里我们用了宏定义 OLED_MODE来决定要设置的 IO 口,后面的就是一些初始化序列了,我们按照厂家提供的资料来做就可以。
值得注意一点的是,因为 OLED 是无背光的,在初始化之后,我们把显存都清空了,所以我们在屏幕上是看不到任何内容的,就像没通电一样,不要以为这就是初始化失败,要写入数据模块才会显示的。
led_wr_byte函数,实现了向SSD1306写入数据,该流程符合8080的[写时序](# 1.2.1 写时序)与[指令格式](#3. 指令格式)
static void oled_wr_byte(uint8_t data, uint8_t cmd)
{
oled_data_out(data);
OLED_RS(cmd);
OLED_CS(0);
OLED_WR(0);
OLED_WR(1);
OLED_CS(1);
OLED_RS(1);
}
8080 并口模式下的 oled_wr_byte 函数还调用 oled_data_out 函数,其定义如下:
/**
* @brief 通过拼凑的方法向OLED输出一个8位数据
* @param data: 要输出的数据
* @retval 无
*/
static void oled_data_out(uint8_t data)
{
GPIOC->ODR = (GPIOC->ODR & 0XFF00) | (data & 0X00FF);
}
oled_data_out 函数的处理方法,就是我们前面说的,因为 OLED 的 D0~D7 对于战舰开发板来说正好顺序接到了 GPIOC[0:7],所以我们只要向 GPIOC 的低位输出一次数据即可实现并口数据输出。
接着,要介绍的是 oled_refresh_gram 更新显存到 OLED 函数,该函数的作用是把我们在程序中定义的二维数组 g_oled_gram 的值一次性刷新到 OLED 的显存 GRAM 中。我们在 oled.c 文件开头定义了如下一个二维数组:
/*
* OLED 的显存
* 每个字节表示 8 个像素, 128,表示有 128 列, 8 表示有 64 行, 高位表示高行数.
* 比如:g_oled_gram[0][0],包含了第一列,第 1~8 行的数据. g_oled_gram[0][0].0,即表示坐标
* (0,0)
* 类似的: g_oled_gram[1][0].1,表示坐标(1,1), g_oled_gram[10][1].2,表示坐标(10,10),
* 存放格式如下(高位表示高行数).
* [0]0 1 2 3 ... 127
* [1]0 1 2 3 ... 127
* [2]0 1 2 3 ... 127
* [3]0 1 2 3 ... 127
* [4]0 1 2 3 ... 127
* [5]0 1 2 3 ... 127
* [6]0 1 2 3 ... 127
* [7]0 1 2 3 ... 127
*/
static uint8_t g_oled_gram[128][8];
该数组值与 OLED 显存 GRAM 值一一对应。在操作的时候我们只需要先修改该数组的值,然后再通过调用 oled_refresh_gram 函数把数组的值一次性刷新到 OLED 的 GRAM 上即可。oled_refresh_gram 函数定义如下:
void oled_refresh_gram(void)
{
uint8_t i, n;
for (i = 0; i < 8; i++)
{
oled_wr_byte (0xb0 + i, OLED_CMD); /* 设置页地址(0~7) */
oled_wr_byte (0x00, OLED_CMD); /* 设置显示位置—列低地址 */
oled_wr_byte (0x10, OLED_CMD); /* 设置显示位置—列高地址 */
for (n = 0; n < 128; n++)
{
oled_wr_byte(g_oled_gram[n][i], OLED_DATA);
}
}
}
oled_refresh_gram 函数先设置页地址,然后写入列地址(也就是纵坐标),然后从 0 开始写入 128 个字节,写满该页,最后循环把 8 页的内容都写入,就实现了整个从 STM32 显存到 OLED显存的拷贝。
/**
* @brief OLED画点
* @param x : 0~127
* @param y : 0~63
* @param dot: 1 填充 0,清空
* @retval 无
*/
void oled_draw_point(uint8_t x, uint8_t y, uint8_t dot)
{
uint8_t pos, bx, temp = 0;
if (x > 127 || y > 63) return; /* 超出范围了. */
pos = y / 8; /* 计算GRAM里面的y坐标所在的字节, 每个字节可以存储8个行坐标 */
bx = y % 8; /* 取余数,方便计算y在对应字节里面的位置,及行(y)位置 */
temp = 1 << bx; /* 高位表示低行号, 得到y对应的bit位置,将该bit先置1 */
if (dot) /* 画实心点 */
{
g_oled_gram[x][pos] |= temp;
}
else /* 画空点,即不显示 */
{
g_oled_gram[x][pos] &= ~temp;
}
}
g_oled_gram [128][8]
二维数组中的 128 代表列数(x 坐标),而 8 代表的是页,每页又包含8 行,总共 64 行(y 坐标),从高到低对应行数从小到大,如表 24.3.2.1 所示:
上表中 G 代表 OLED_GRAM,G[0][0]就表示 OLED_GRAM [0][0]。比如,我们要在 x=3,y=9 这个点写入 1,则可以用这个句子实现:
一个通用的在点(x,y)置 1 表达式为:
其中 x 的范围为:0~127;y 的范围为:0~63。
该函数有 3 个形参,前两个是横纵坐标,第三个 t 为要写入 1 还是 0。该函数实现了我们在OLED 模块上任意位置画点的功能。
5.总结
OLED可应用多种通信协议,8080并口,IIC,SPI等,通过协议规定的时序与命令向SSD1306写入,驱动OLED进行显示
8 行,总共 64 行(y 坐标),从高到低对应行数从小到大,如表 24.3.2.1 所示:
[外链图片转存中…(img-MRvK1pnw-1724453272197)]
上表中 G 代表 OLED_GRAM,G[0][0]就表示 OLED_GRAM [0][0]。比如,我们要在 x=3,y=9 这个点写入 1,则可以用这个句子实现:
一个通用的在点(x,y)置 1 表达式为:
其中 x 的范围为:0~127;y 的范围为:0~63。
该函数有 3 个形参,前两个是横纵坐标,第三个 t 为要写入 1 还是 0。该函数实现了我们在OLED 模块上任意位置画点的功能。
5.总结
OLED可应用多种通信协议,8080并口,IIC,SPI等,通过协议规定的时序与命令向SSD1306写入,驱动OLED进行显示