模块的购买途径不需要多说了,TB上有,本文介绍的是SSD1306为主控芯片的0.96寸OLED屏幕,数据接口为SPI和I2C的在命令上并没有区别。

本文例子是I2C协议的oled模块
请添加图片描述
请添加图片描述

另外,在I2C协议的模块后方有一个选择从机地址的电阻,用电阻连接那边,从机地址就会被设置

请添加图片描述
我的是I2C协议的OLED模块,从机地址是0x78

基础命令

首先我们定义一个函数,用来将数据传输给OLED模块,函数具体的实现与模块使用的协议有关

void SendByte(u8 dat)

这个函数负责将单片机的命令通过某个协议传输给OLED
输入的是8bit数据,无输出

发送命令

命令的用的是8bit数据,而且并不是所有的命令位有效,进入发送命令模式后,如果发送的是命令表中没有的命令,则会认为命令无效

发送命令需要先设置发送的是命令,即先发送0x00

SendByte(0x00);

之后再发送命令的内容,之后发送的所以内容都被认为是命令

可以认为是一个多级菜单,第一级是选择命令还是数据
在这里插入图片描述

单句命令

还是类比成多级菜单,这里就是选择发送的命令,只不过这里有两种模式了

在这是第二级,单句命令像这样
在这里插入图片描述
发送命令(按下按钮)后不需要其他设置就直接执行了
这种命令不算多

例子

SendByte(0xAE);		 //关闭显示
SendByte(0xA4); 	//设置整个显示打开/关闭
SendByte(0xAF); 	//开启显示
SendByte(0xA4); 	//设置整个显示打开/关闭

多句命令

这里还是第二级,也就是说单句和多句只是作者的分类,SSD1306并没有这么分类
在这里插入图片描述
就像这样,在第二级中先设置需要设置的内容(点击按钮),之后再选择内容(第三级菜单),或者写入数据

	SendByte(0xD5); //设置显示时钟分频比/振荡器频率
	SendByte(0x80);

常用命令介绍

初始化命令

这部分基本上不需要修改,注释放上了,感兴趣的请看SSD1306芯片的官方文档

	SendByte(0xAE);		 //关闭显示

	SendByte(0xD5); //设置显示时钟分频比/振荡器频率
	SendByte(0x80);

	SendByte(0xA8); //设置多路复用率
	SendByte(0x3F);

	SendByte(0xD3); //设置显示偏移
	SendByte(0x00);

	SendByte(0x40); //设置显示开始行

	SendByte(0xA1); //设置左右方向,0xA1正常 0xA0左右反置

	SendByte(0xC8); //设置上下方向,0xC8正常 0xC0上下反置

	SendByte(0xDA); //设置COM引脚硬件配置
	SendByte(0x12);

	SendByte(0x81); //设置对比度控制
	SendByte(0xCF);

	SendByte(0xD9); //设置预充电周期
	SendByte(0xF1);

	SendByte(0xDB); //设置VCOMH取消选择级别
	SendByte(0x30);

	SendByte(0xA4); //设置整个显示打开/关闭

	SendByte(0xA6); //设置正常/倒转显示

	SendByte(0x8D); //设置充电泵
	SendByte(0x14);

	SendByte(0xAF); //开启显示

显示控制命令

这是个单句命令

功能命令
关闭显示0xAE
开启显示0xAF

对比度设置

这是个双句命令

功能命令
进入对比度设置模式0x81

之后输入对比度数值范围是0x00 - 0xFF

对比度实际上在这里就是设置发光部分的亮度,数值越大,亮度越大

显示模式

功能命令
阳码显示0xA6
阴码显示0xA7

实际上就是设置没有显示部分是白还是黑,阳码就是没有显示的部分不发光

发送数据

这个没什么好说的,首先发送进入发送数据模式,之后发送数据即可,之后发送的所以内容都被认为是数据

SendByte(0x40);

进入发送数据模式

寻址模式

寻址模式有三种,水平寻址模式,垂直寻址模式,页寻址模式
最常用的是页寻址模式,
又因为水平寻址方式和垂直寻址方式在写入整个屏幕时方便,水平寻址模式和页寻址模式的取模方法相同
所以这里介绍水平寻址模式和页寻址模式

点阵和页

OLED屏幕就是一个个小的有机自发光二极管组成的阵列
作者作为例子的屏幕的分辨率是128*64
即每行有128个发光二极管,一共有64行
如示意图
在这里插入图片描述
页是芯片设计者为了方便将同一列的8个点阵编成一组,用一个8bit数表示,这样的8行128个数被称为1页
请添加图片描述
用0和1来代表灭和亮(阳码),越靠近上方的是低位
在这里插入图片描述

左边的实际的点阵,右边是等效的数,这样编码之后的这页这列的值为0x05

请添加图片描述

这是示意图,经过编码之后,128*64的OLED屏幕有8页,128行

设置方法

  1. 进入命令设置模式
  2. 进入寻址设置模式
  3. 选择寻址模式
模式命令
水平寻址模式0x00
垂直寻址模式0x01
页寻址模式0x02
SendByte(0x00);	//命令设置
SendByte(0x20);	//寻址设置
SendByte(0x02);	//页寻址

水平寻址模式

寻址特点

请添加图片描述

在这里插入图片描述
这是示意图

核心特点为:横向编码,列地址自动加,遇到设置范围的页尾时自动跳转到下一页,传输到设置范围的最后一页最后一列时自动复位

设置流程

  1. 进入发送命令模式
  2. 设置寻址模式
  3. 设置列地址范围
  4. 设置页地址范围
	SendByte(0x00);
	SendByte(0x20); //设置寻址模式 (0x00水平/0x01垂直/0x02页)
	SendByte(0x00); //水平寻址模式
	SendByte(0x21); //设置列地址
	SendByte(0x00);
	SendByte(0x7f);
	SendByte(0x22); //设置页地址
	SendByte(0x00);
	SendByte(0x07);

列地址范围是0-127,页地址范围是0-7,共128列,8页,也就是全屏

作者使用水平地址寻址是用于更新整个屏幕,因此设置的地址范围是全屏,读者如果有其他用途,可以自行设置,

使用水平地址寻址可以持续发送数据,不需要设置地址,每次发送整个屏幕的数据即可,用于整屏更新非常方便

页寻址模式

寻址特点

在这里插入图片描述

从设定的页和列开始发送数据,列地址自动累加,页地址不会更新,如果超出范围则超出部分无效,可以不用事先指定每页中每列的长度

设置流程

  1. 进入命令发送模式
  2. 设置寻址模式
  3. 设置页地址
  4. 设置列地址起始位
	SendByte(0x00);	//发送命令
	SendByte(0x20); //设置寻址模式 (0x00水平/0x01垂直/0x02页)
	SendByte(0x10); //页寻址模式

之后需要紧跟页地址和列地址

地址设置

页地址

命令是8位的,高四位在页地址设置时是固定值0b1011
在这里插入图片描述
Y[3:0]为页地址的编号
因此我们可以使用这句命令生成页地址数据并发送

SendByte(0xb0 | (y & 0x0f));

y是页地址的编号,使用与(&)命令取得y的低4位(y & 0x0f)
之后使用或命令将这低四位与固定前缀0xb连接起来(0xb0 | (y & 0x0f))

列地址

设置列地址高四位的前4位固定是0b0001,低四位的前4位固定是0b0000
如图
在这里插入图片描述
x[7:0]为列地址

	SendByte(((x & 0xf0) >> 4) | 0x10);	//列地址高4位
	SendByte(x & 0x0f);					//列地址低4位

x是列地址数据
首先看发送高四位的程序,先使用与命令(&)取得x的高4位(x & 0xf0)
之后向右移4位,将高4位数据放到低4位((x & 0xf0) >> 4)
之后使用或命令(|)加上固定前缀0x1即可(((x & 0xf0) >> 4) | 0x10)
再看发送低四位命令
因为地址低四位的高四位为0x0,因此只需要使用与命令(&)将高四位置零即可
(x & 0x0f)

设置地址之后,就可以在这一页发送不定长度的数据了
注意:进入下一页时需要重新设置地址

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐