ESP32驱动OLED SSD1306详解

一、我的OLED屏及开发环境简介

        我用EPS32S3开发板,Platformio工具,Arduino代码框架进行开发。

        淘宝上买的便宜0.96寸OLED板子128*32,蓝黄双色(其实就是固定了0-8行黄色,剩余蓝色像素,不能自己选择哪儿显示不同颜色),6线SPI接口,接口这个应该是容易让大家混淆的。

        根据芯片手册,IIC和SPI都是用SSD1306这个驱动芯片,淘宝厂家将其组装成模块过程通过不同的布线可以生产出不同的接口。我这块没有CS(片选线),经研究,其CS已经接地了,永远是低电平。D1是MOSI(ESP32S3的13脚),D0是SCK(接12脚),VCC接3.3V。因此,SPI协议是无法读取SSD1306的,只能单向写入。

二、驱动原理和字符取模简介

1、驱动原理        

        OLED液晶屏硬件的显像原理可以看这家厂家的文章:

        https://www.dragonlcm.com/22265.html

        行叫COM,阴极,接地,SSD1306自动控制每行依次接通,不需要我们控制。

        列叫SEG,阳极,通过写入的0和1控制通断。

        由于这是单色屏幕,显像原理就是芯片每次控制一行通,该行上有128个像素点,其0和1的信息记录在SSD1306的GDDRAM上,由芯片自动控制从GDDRAM读取并显示在OLED上,GDDRAM上是什么样的图形方向,OLED上就怎样显示,除非配置寄存器故意搞镜像。

2、字符取模

        这个图来自官方手册,再怎么认真理解都不为过,因为容易让人混乱。这个图讲的是编程时如何写图形信息入GDDRAM。这儿引入页这个概念是方便的。一页就是8行,每行128个像素点,至于为何是8行,应该与行业诞生时的一些环境有关,ASCII的一个字符能在8行里面显示出来,8也是一个byte。

        打开PCtoLCD取字模软件(网上容易获得),取个A,8x8像素:

                       

        从左列至右列逐列取模结果是{0x20,0x10,0x0C,0x0A,0x0C,0x10,0x20,0x00},注意最上行像素点是字节的低位。按照这个方式将上述字节自左至右逐列填入GDDRAM,就能正常方向显示A字。按照8x8这个字符大小布局,一页从左至右可以刚好显示16个英文字符,填满一页,页的概念是方便我们写入字。

        

三、代码和数据手册解读

1、如何传入数据

        传统spi模式的话,有CS引脚,拉低CS后就可传输一个byte的字节。但我的模块是没CS,所以省去拉低CS这一步,任何时候想写就写信息。传寄存器操作命令时,先将DC引脚拉高,然后直接写1byte寄存器命令进去;传图像数据给GDDRAM时,DC拉低,直接写1byte数据进去。MCU的SPI传输模式用默认的,就是LSBfirst,SCK上升沿采样。

        SSD1306的寄存器操作逻辑类似一级菜单和二级子菜单这样。所以会有单字节命令、双字节命令和多字节命令。

        这儿截图有2个操作命令。第一个对比度配置命令是双字节命令,需要先SPI传输0x81,然后马上传输0x7F,就能将对比度调成118(范围是0~255)。0x81是类似一级菜单,打开了这个菜单才能进入下一级子菜单设置具体对比度数值。图中凡是A0、A1、X0这些位都是允许用户自己填数值的。他已经写上1或0的位置是不允许自行修改数值。

        第二个Entire display on配置是单字节命令,1至7位都已经厂家定好了,只能修改0位,所以这儿只能有2种配置选择,第0位值为1或0,对应的整个字节命令值就是0xA4或0xA5。

2、寻址模式

        寻址模式比较少人讲得深入,其实这儿涉及的是从MCU按什么顺序写入GDDRAM的事,不是芯片如何从GDDRAM搬到OLED上的事。

(1)页寻址

        这个是默认的模式。特色用途就是方便玩家灵活控制整个屏幕上哪个区域写入信息,中间一块、边角一块都行,尤其适用于写入文字。像绿色箭头所示,同一页内,自左至右逐列从MCU写入图像信息到GDDRAM,写入第一列后,芯片自动控制指针到第二列,玩家不用控制,一口气将128byte信息连续不间断写入即可。第128列写完后,列指针跳回到第0列,但页指针不懂得往下移动到下一页,这是页寻址模式跟横向寻址模式的最大区别,页寻址模式需要玩家手动输入命令0xB1后,才能从0页跳到1页继续写入信息。如果页不跳动,就能约束在同一水平区域上不断刷新图像信息,而屏幕其他区域信息不改动这样的效果。

(2)横向寻址

        

        横向寻址模式,特色用途是整个屏幕一齐刷新画面信息,适用于整个屏幕的图像显示,或视频这种场景。上图的横向绿色箭头跟页寻址一样,先是自左至右写完一页GDDRAM,芯片会控制页指针自动跳到下一页开头继续写,这样写满整个屏幕所有像素点。对于玩家来说,代码是最简单的,不用任何控制,无脑不间断输入128像素点的信息即可。

(3)竖向寻址

        这个跟横向类似,不解读了。

3、寄存器详解

(1)初始化配置

        这三张图先讲,因为代码也是先用这三张图。这三个表格的寄存器都是配置用的,大部分是初始化时做一次就行。玩家要先调好初始化这几个寄存器的参数,把图像调正再做下一步。

        其实芯片手册最后一页有个流程图就完整讲了初始化要配置哪些寄存器,我就不再重复,看代码:

void init_ssd1306()
{
  digitalWrite(pinRES,LOW);
  delayMicroseconds(4);
  digitalWrite(pinRES,HIGH);
  writeCMD(0xA8,0x3F);  //MUX ratio 64
  writeCMD(0xD3,0x00); //Display offset
  writeCMD(0x40); //Display startline
  writeCMD(0xA1); //segment remap
  writeCMD(0xC8); //COM scan directionv从0-N
  writeCMD(0xDA,0x02); //COM pin是否交替开通
  writeCMD(0x81,0x8F); //对比度范围0-255
  writeCMD(0xA4); //display on
  writeCMD(0xA6); //是否反色显示
  writeCMD(0xD5,0xF0);//设置晶振频率以及分频,不分频,最快频率
  writeCMD(0x8D,0x14);//电荷泵打开
  writeCMD(0x20, 0x02); // 用页寻址模式
  writeCMD(0xAF); //display on
  delay(100);
}

        RES引脚拉低由拉高是手册说的开机上电的步骤。

        Set Contrast Control设置对比度,0~255,不进行初始化也没问题。

        Entire Display On这个容易与Set Display On/Off 这个命令混淆。Entire On其实就是将全屏所有像素点都点亮,就是整个GDDRAM都填满1,应该容易想象出来。而Set Display On/OFF就是真正意义上的亮屏、熄屏。下图是Entire Display on的画面。

entire display on

        Set Inverse Display像素反转,1和0反转。

        Set Display On/Off上面已提及,注意亮屏熄屏有个时间延迟,毫秒级的。

        Set Display Start Line就是设置图像内容的第一行显示在屏幕的第x行。

        Set Segment Re-map就是列的镜像颠倒,就是图像左右颠倒,照镜。

        Set Multiplex ratio就肯定是设置满屏64行了,这个英文我不了解,应该是设置图像在屏幕显示的区域大小。

        Set COM Output Scan Direction其实这个就是行的镜像颠倒,图像上下颠倒。

        Set Display Offset图像向下位移多少行。这个跟StartLine不一样的是,如果图像下方移出屏幕边缘,会接着在屏幕上面区域显示。

        Set COM Pins Hardware Config,比如一个A字原本是8行,如果设置了alternative COM pin config,A的字符会变成4行显示,中间间隔行被抽走了。

        Set Diaplay Clock Divide, Frequency,这个就不用管了,设置最快就行, 当然有的场合要考虑功耗。

        Set Pre-Charge Period,用默认设置就行。

        Set Vcomh Deselect Level,其实这个是怕不显示像素的屏幕黑色区域有泛白光,不够黑而做的反向电压,默认值也很够了,不用设置。

(2)寻址和写入的命令

       从MCU写信息到GDDRAM过程,需要用这些寄存器指令。

       Set Lower Colum Start Addr 和High Column这两个一起看。只有页寻址模式才能用,是控制在一页里面哪列开始写数据,其实也相当于将一页里面的图像右移多少像素的意思。Lower column相当于小数,Higher Column相当于整数,两个加起来就得出要移动多少像素。Lower columnn控制右移1-16像素,而Higher column每加1,都令图像右移16像素。有时你认为只需要右移10像素就够,就可以不写Higher Column这个寄存器的命令了,仅写Lower column的0x0A命令就可。两个命令不是要求必须同时配置成0x00的,可以只配置其中一个。

(3)屏幕滚动

        

        这个是多字节寄存器。要一口气写入7条命令。一次要滚动至少一页。记得设置完任何的滚动配置后,还要再来一条激活滚动的命令0x2F。如果取消激活0x2E,图像不会在当前位置停下,而是回到最开始安放的位置。

斜滚动

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值