1.OLED屏幕介绍
OLED,及有机发光二极管(Organic Light-Emitting Diode),OLED由于同时具备自发光,不需要背光光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制造比较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。

1)0.96 寸 OLED 有黄蓝、白、蓝三种颜色可选,其中黄蓝是屏上 1/4 部分为黄光,下 3/4 为蓝;而且是固定区域显示固定颜色,颜色和显示区域均不能修改;白光则为纯白,也就是黑底白字;蓝色则为纯蓝,也就是黑底蓝字。
2)分辨率为 128*64
3)多种接口方式,OLED 裸屏总共种接口包括:6800、8080 两种并行接口方式、3 线或 4 线的串行 SPI 接口方式(通信速度快,但占用引脚多)、2线 IIC 接口方式(通信速度慢,但占用引脚少),这里使用的四针 0.96 寸 OLED 显示屏,该显示器采用2线IIC总线协议通信。

屏幕的驱动IC为SSD1306,是一个单片CMOS、OLED/PLED驱动芯片可以驱动有机/聚合发光二极管点阵图形显示系统。由128Segments和64Commons组成。该芯片专为共阴极OLED面板设计。SSD1306中还嵌入了对比度控制器、显示RAM和晶振,并因此减少了外部器件和功耗。由256级亮度控制。数据/命令的发送有三种接口可以选择:6800/8000串口、IIC接口和SPI接口(STM32与屏幕通信其实就是与驱动IC通信)。

SSD1306其具有内部升压功能,所以在设计的时候不需要再专一设计升压电路,当然也可以选用外部升压,具体设计可参考数据手册。SSD1306芯片的显存总共为128*64bit大小,SSD1306将这些显存分为了8页,每页包含了128个字节,这样刚好128*64的点阵大小。

OLED屏幕有三种寻址方式,页寻址方式、水平寻址方式和垂直寻址方式,默认选择页寻址方式,其他寻址方式因为不使用所以暂时不讲,到了第四篇优化刷新速率时用到时会讲到,有兴趣可以到第四篇看看。
页地址模式:使用页寻址方式对GRAM进行操作时,列地址指针会自动递增。当列地址指针到达列结束地址时,重置为开始地址,但页地址指针不变。用户必须设置新的页面和列地址,以便访问下一页GRAM内容。
将整个OLED屏幕一分为八,也就是8页,每页包含128字节,一个字节有8位(0000 0000 ~ 1111 1111) ,低位在前。如果想要在第0列第3行显示一个点,可配置0x08(0000 0100)写入。

SSD1306芯片的指令用于控制OLED的显示功能和效果。SSD1306指令比较多,这里介绍几个常用指令即可,第一个指令是显示开关指令,第二个和其余两个指令是用于设置SSD1306的GRAM写入位置(可参考下面的代码)。三种设置内存地址模式:页地址模式,水平地址模式和垂直地址模式。
指令0xAE/0xAF:0xAE为关闭显示命令,0xAF为开启显示命令。
指令0xB0~0xB7:用于设置页地址,其低三位的值对应着GRAM页地址。
指令0x00~0x0F:用于设置显示时的起始地址低四位。
指令0x10~0x1F:用于设置显示时的起始地址高四位。

用指令设置写位置的起始光点:
/**
* @brief OLED设置光标位置
* @param Y 以左上角为原点,向下方向的坐标,范围:0~7
* @param X 以左上角为原点,向右方向的坐标,范围:0~127
* @retval 无
*/
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
OLED_Write_Command(0xB0 | Y); //设置Y位置
OLED_Write_Command(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位
OLED_Write_Command(0x00 | (X & 0x0F)); //设置X位置低4位
}
图形显示数据RAM(GRAM):是一个位映射静态RAM,保存要显示的位模式。内存大小为128*64位,可分为8页,从页0到页7,用于黑白128*64点阵显示。写入指令0xA0/0xA1和指令0xC0/0xC8定义显示方式。

清屏函数(GRAM写0):
/**
* @brief OLED清屏
* @param 无
* @retval 无
*/
void OLED_Clear(void)
{
uint8_t i = 0, j = 0;
for (j = 0; j < 8; j++) {0 ~ 7页
OLED_SetCursor(j, i);//选择起始光点
for(i = 0; i < 128; i++) {0 ~ 127列
OLED_Write_Data(0x00);//写入数据
}
}
}
列地址指针自增,低位在前:
/**
* @brief OLED清屏
* @param 无
* @retval 无
*/
void OLED_Clear(void)
{
uint8_t i = 0, j = 0;
for (j = 0; j < 8; j++) {
OLED_SetCursor(j, 0);//列地址指针会自动递增写0也可以
for(i = 0; i < 128; i++) {
OLED_Write_Data(0x80);//1000 0000 对高位写1
}
}
}
