SSD1306驱动理解
写在前面:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
先看一下官方手册上给出的驱动流程:
然后下面是个人用的驱动流程:
void OLED_Init(void)
{
OLED_Config();
OLED_SCK(HIGH); // 空闲态时,SCLK处于高电平
OLED_CS(HIGH); // 关闭选择输入
/* 从上电到下面开始初始化要有足够的时间,即等待 RC复位完毕 */
OLED_RST(LOW); // 复位(低电平有效)
OLED_Delay_ms(100);
OLED_RST(HIGH);
OLED_Delay_ms(30);
OLED_Write_Cmd(0xAE); // 关闭OLED -- turn off oled panel
OLED_Write_Cmd(0xD5); // 设置显示时钟分频因子/振荡器频率 -- set display clock divide ratio/oscillator frequency
OLED_Write_Cmd(0x80); // \ set divide ratio, Set Clock as 100 Frames/Sec
OLED_Write_Cmd(0x20); // 设置内存寻址模式 -- Set Memory Addressing Mode (0x00 / 0x01 / 0x02)
OLED_Write_Cmd(0x02); // \ Page Addressing
OLED_Write_Cmd(0xA8); // 设置多路传输比率 -- set multiplex ratio (16 to 63)
OLED_Write_Cmd(0x3F); // \ 1 / 64 duty
OLED_Write_Cmd(0xDA); // 设置列引脚硬件配置 -- set com pins hardware configuration
OLED_Write_Cmd(0x12); // \ Sequential COM pin configuration,Enable COM Left/Right remap
/* ----- 方向显示配置 ----- */
OLED_Write_Cmd(0xA1); // 设置段重映射 -- Set SEG / Column Mapping 0xA0左右反置(复位值) 0xA1正常(重映射值)
OLED_Write_Cmd(0xC8); // 设置列输出扫描方向 -- Set COM / Row Scan Direction 0xc0上下反置(复位值) 0xC8正常(重映射值)
/* ----- END ----- */
OLED_Write_Cmd(0x40); // 设置设置屏幕(GDDRAM)起始行 -- Set Display Start Line (0x40~0x7F)
OLED_Write_Cmd(0xD3); // 设置显示偏移 -- set display offset (0x00~0x3F)
OLED_Write_Cmd(0x00); // \ not offset
OLED_Write_Cmd(0x81); // 设置对比度 -- set contrast control register (0x00~0x100)
OLED_Write_Cmd(0xCF); // \ Set SEG Output Current Brightness
OLED_Write_Cmd(0xD9); // 设置预充电期间的持续时间 -- set pre-charge period
OLED_Write_Cmd(0xF1); // \ Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_Write_Cmd(0xDB); // 调整VCOMH调节器的输出 -- set vcomh (0x00 / 0x20 / 0x30)
OLED_Write_Cmd(0x20); // \ Set VCOM Deselect Level
OLED_Write_Cmd(0x8D); // 电荷泵设置 -- set Charge Pump enable / disable (0x14 / 0x10)
OLED_Write_Cmd(0x14); // \ Enable charge pump during display on
OLED_Write_Cmd(0xA4); // 全局显示开启(黑屏/亮屏) -- Entire Display On (0xA4 / 0xA5)
OLED_Write_Cmd(0xA6); // 设置显示方式(正常/反显) -- set normal display (0xA6 / 0xA7)
OLED_Write_Cmd(0xAF); // 打开OLED -- turn on oled panel
OLED_Fill(0x00); // 初始清屏
OLED_Coord(0,0); // 设置原点坐标(0, 0)
}
一、 图形显示数据RAM (GDDRAM)
先来认识一下图形是怎样显示的
图一:
如上面图一所示:RAM分为8页,从PAGE0到PAGE7;列地址有128个,从SEG0到SEG127。
每一页里面有八位数据(bits),数据书写为从低位LSB到高位MSB,如下面图二所示:
图二:
然后,在上面流程里面有:
/* ----- 方向显示配置 ----- */
OLED_Write_Cmd(0xA1); // 设置段重映射 -- Set SEG / Column Mapping 0xA0左右反置(复位值) 0xA1正常(重映射值)
OLED_Write_Cmd(0xC8); // 设置列输出扫描方向 -- Set COM / Row Scan Direction 0xc0上下反置(复位值) 0xC8正常(重映射值)
/* ----- END ----- */
这两个书写指令,第一个对应的是段重映射(左右反置),第二个对应的是列输出扫描(上下反置),扫描方式如图一绿色所示(映射值),黑色的为正常(复位值),对应的指令具体解释请往下慢慢看
二、 指令表
Ⅰ、 基本指令简介
Ⅱ、 应用指令详解
1、地址设置命令
(1)页地址模式下设置列起始地址低位(Set Lower Column Start Address For Page Addressing Mode)(00h~0Fh)
此指令用于在页地址模式下设置GDDRAM的列起始地址(8位)的低4位, 每一次数据访问都会增加列地址。
(2)页地址模式下设置列起始地址高位(Set Higher Column Start Address For Page Addressing Mode)(10h~1Fh)
此指令用于在页地址模式下设置GDDRAM的列起始地址(8位)的高4位, 每一次数据访问都会增加列地址。
(3)设置内存地址模式(Set Memory Addressing Mode)(20h)
SSD1306中有3种不同的内存寻址模式:页寻址模式、水平寻址模式和垂直寻址模式。此命令将内存寻址方式设置为上述三种模式之一。其中,“COL”表示GDDRAM列(column)
页地址模式(A[1:0]=10b)
当处于此模式时, 在GDDRAM访问后(读/写), 列地址指针将自动增加1。如果列地址指针到达列终止地址, 列地址指针将复位到列起始地址, 但页地址指针不会改变。
为了访问GDDRAM中下一页的内容, 用户必须设置新的页地址和列地址。页地址模式下页以及列地址指针的行为如下图所示
通常在页地址模式下访问GDDRAM, 需要如下步骤来定义起始RAM访问指针指向:
-通过命令(B0h-B7h)设置目标显示位置页起始地址
-通过命令(00h-0Fh)设置列起始地址低位
-通过命令(10h-1Fh)设置列起始地址高位
例如, 如果页地址是B2h, 列地址低位是03h, 列地址高位是10h, 则表示起始列为PAGE2的SEG3, GDDRAM访问指针的指向如下图所示
水平地址模式(A[1:0]=00b)
当处于此模式时, 在GDDRAM访问后(读/写), 列地址指针将自动增加1。如果列地址指针到达列终止地址, 列地址指针将复位到列起始地址, 且页地址指针将自动增加1。
水平地址模式下页以及列地址指针的行为如下图所示, 如果列地址指针和页地址指针都到达各自的终止地址时, 他们将被重置为列开始地址和页开始地址。(图中虚线)
垂直地址模式(A[1:0]=01b)
当处于此模式时, 在GDDRAM访问后(读/写), 页地址指针将自动增加1。如果页地址指针到达页终止地址, 页地址指针将复位到页起始地址, 且列地址指针将自动增加1。
垂直地址模式下页以及列地址指针的行为如下图所示, 如果列地址指针和页地址指针都到达各自的终止地址时, 他们将被重置为列开始地址和页开始地址。(图中虚线)
通常在GDDRAM读写和水平/垂直寻址模式下,定义RAM访问指针位置需要以下步骤::
-通过命令(21h)设置目标显示位置列起始地址以及列终止地址
-通过命令(22h)设置目标显示位置页起始地址以及页终止地址
(4)设置列地址(Set Column Address)(21h)
此指令用于设置GDDRAM的列起始地址和列结束地址, 并使列地址指针(指向GDDRAM中当前访问的列地址)指向列起始地址。
若内存地址模式为水平地址模式, 在访问一列数据后, 列地址指针将增加到下一个列地址。当结束访问终止列地址时, 列地址指针将复位至列起始地址, 且行地址指针将增加到下一行。
(5)设置页地址(Set Page Address)(22h)
此指令用于设置GDDRAM的页起始地址和页结束地址, 并使页地址指针(指向GDDRAM中当前访问的页地址)指向页起始地址。
若内存地址模式为垂直地址模式, 在访问一页数据后, 页地址指针将增加到下一个页地址。当结束访问终止页地址时, 页地址指针将复位至页起始地址。
下图展示了例子中列地址指针和页地址指针的移动方式: 列起始地址设为2, 列终止地址设为125, 页起始地址设为1, 页终止地址设为6, 并使用水平地址模式。
在此情况下, GDDRAM数据可访问范围是从第2列到第125列,仅从第1页到第6页。同时列地址指针被设为2, 页地址指针被设为1。在访问数据后, 列地址自动增加1, 以访问下一个RAM位置进行下一次读取/写入操作(图中实线)
每当列地址指针访问完结束列地址(125)时, 列地址指针复位到列2, 页地址指针自动增加1(图中实线), 当访问终止页地址6和终止列地址125所在数据后, 页地址指针复位到1, 列地址指针复位到2(图中虚线)
2、图形加速指令
(1)水平滚动配置(Horizontal Scroll Setup)(26h/27h)
此指令用于配置水平滚动参数和确定滚动起始页、终止页和滚动速度
在发出此命令之前,必须禁用水平滚动条(2Eh)。否则,RAM内容可能被破坏。
SSD1306的水平滚动设计为128列滚动, 以下是使用水平滚动的例子:
向右滚动一列
向左滚动一列
水平滚动配置例子
(2)连续垂直和水平滚动配置(Continuos Vertical and Horizontal Scroll Setup)(29h/2Ah)
此指令用于设置连续的垂直滚动参数,并确定滚动的起始页、结束页、滚动速度和垂直滚动偏移量。
命令29h/2Ah的字节B[2:0]、C[2:0]和D[2:0]用于设置连续水平滚动。字节E[5:0]用于设置连续垂直滚动偏移量。所有这些字节一起用于设置连续对角滚动(水平+垂直)。如果垂直滚动偏移字节E[5:0]设置为0,则只执行水平滚动(和命令26/27h一样)
同样,在发出此命令之前,必须禁用水平滚动条(2Eh)。否则,RAM内容可能被破坏。
以下是使用垂直和水平滚动的例子:
(3)禁用滚动(Deactivate Scroll)(2Eh)
此指令用于停止滚动,发送2Eh命令以禁用滚动操作后,需要重写ram数据。
(4)启用滚动(Activate Scroll)(2Fh)
此指令用于启动滚动, 并且只有在滚动设置命令定义滚动设置参数后才应发出:26h/27h/29h/2Ah。最后调用滚动参数命令的配置将覆盖之前调用过滚动参数命令的配置
在**滚动之后,禁止执行以下操作
①对RAM的访问
②改变水平滚动配置参数
(5)设置垂直滚动区(Set Vertical Scroll Area)(A3h)
此指令用于设置垂直滚动区, 对于垂直滚动功能(29/2Ah), 垂直滚动的行数可以大于或小于多路传输比率(MUX ratio)