OLED模块学习指南

前言

OLED模块是一种通用型外设,可以被各种型号的微控制芯片操控。在此编者以TI公司生产的TMS320F28027芯片为例,根据自己使用该模块的经验,自定义了一系列使用方便的操作函数,并对整个模块的关键部分进行了讲解分析,希望能够对初学者起到一定的帮助。
(这不是我原创,我也不知道在哪翻到的一个PDF,网上还没有)

一、模块及驱动简介

1.引脚
OLED模块引脚OLED模块学习指南_第1张图片
单片机控制引脚
OLED模块学习指南_第2张图片
2.控制原理
OLED器件内部有一个存储区,用来保存当前屏幕显示图像的信息。对OLED显示的控制实际上就是对OLED内部存储区的写操作。
整个OLED屏幕由128列X64行的点阵构成。为了便于操控,从上到下每8行划分成一页,共8页,所以整个屏幕划分为128列X8页。
向OLED发送数据的最小单位是一个8位二进制数,数据(从最低位到最高位)的每一位(0/1) 对应屏幕上(从上到下)的一个点(灭/亮),这意味着控制的最小单元是某一列连续的8个点。
3.常用驱动函数
为便于使用,编者对底层驱动代码进行了层层封装。
主要有以下几个常用函数:
OLED模块学习指南_第3张图片

二、案例讲解

为了便于学者快速入门,单从应用的角度出发讲解,暂时忽略通用的配置内容。最好的讲解莫过于例子,下面的代码较为清楚的展示了控制函数的调用方法。
1.点亮屏幕

void wShowOLED4Corners()
{
     
/*128*64 => 128*8*/
//(1,1)左上角
wOLED_SetRank(1);//设置列地址
wOLED_SetPage(1);//设置页地址
wOLED_WriteData(0x01);//2#0000_0001#
//(128,1)右上角
wOLED_SetRank(128);//设置列地址
wOLED_SetPage(1); //设置页地址
wOLED_WriteData(0x01); //2#0000_0001#
//(1,64)左下角
wOLED_SetRank(1); 
wOLED_SetPage(8); 
wOLED_WriteData(0x80); //2#1000_0000#
//(128,64)右下角
wOLED_SetRank(128); 
wOLED_SetPage(8); 
wOLED_WriteData(0x80); //2#1000_0000#
//显示字模
wShow0LED16X16(1, 50, 0);//在第一页中央显示"开"
wShowOLED16X16(1 , 50+16,1);//在第一页中央显示“始”

OLED模块学习指南_第4张图片
说明:
通过以上代码应该能够看出控制的步骤和对应关系。
**对某一位置进行操作需要三个步骤:**设置列地址,设置页地址,写入数据。写入的数据一般用十六进制表示,这样有两个好处:使得代码整齐;方便转换为二进制了解具体信息。
写入字模只需直接调用wShowOLED16X80或wShowOLED16X160函数即可,三个参数分别为开始的页地址,开始的列地址和字模所在的位置。
2.显示进度条动画

void wShowProgressBar()
{
     
	//产生进度数据
	static int progress = 0;
	if (progress < 100)
		progress += 1;
	else
		progress = 0;
	//显示进度数据
	int hundred = progress / 100;//取出百位数
	int ten = progress / 10;//取出十位数
	int single = progress % 10;//取出个位数
	if (hundred)
		wShow0LED16X8(150,hundred); // 显示百位
	else
		wShowOLED16X8(15030);//消除百位
	if (ten == 0)
		wShowOLED16X8(150 + 830);//消除十位
	else if (ten< 10)
		wShowOLED16X8(150 + 8,ten);//显示十位
	else
		wShowOLED16X8(150 + 80);//显示十位
	wShowOL ED16X8(150 + 16,single) ;//显示个位
	wShowOLED16X8(150 + 24, 14);//显示%
	
	//显示进度条
	inti=0;
	
	//从头到尾写入
	wOLED_SetRank(14) ;//设置列地址
	wOLED_SetPage(5);//设置页地址
	for (i = 0; i < progress; i++)
	wOLED_WriteData(0xFF);//2#1111_ 1111#

	//设置延时
	if (progress < < 100)
		wOLED_delay(1E5);//延时0.1秒
	else
	{
     
		wOLED_delay(3E6);//延时3秒
		wOLED_FullShow(0x00);//清屏
	}
}

说明:
从以上代码可以学习到以下几点:
1.显示动态数据的方法
分别取出数据的每一位,然后分别调用wShowOLED16X8(函数将其显示出来。数据的字模存储在字模库文件Font.h之中。

unsigned char const my16x8[] =
{
     
0x00,0xE0,0xF0,0x18,0x08,0x18,0xF0,0xE0,
0x00,0x0F,0x1F,0x30,0x20,0x30,0x1F,0x0F,/*"0", 0*/

0x00,0x10,0x10,0xF8,0xF8,0x00,0x00,0x00,
0x00,0x20,0x20,0x3F,0x3F,0x20,0x20,0x00,/*"1",1*/

0x00,0x70,0x78,0x08,0x08,0x88,0xF8,0x70,
0x00,0x30,0x38,0x2C,0x26,0x23,0x31,0x30,/*"2",2*/
....

wShowOLED16X80函数的定义如下:

void wShowOLED16X8(uint16_t Page,uint16_t Rank,uint16_t Over)
{
     
	uint16_t i, j;
	for(i=0;i<2;i++)
	{
     
		wOLED_SetRank(Rank);//设置列地址
		wOLED_SetPage(Page + );//设置页地址
		for(j=0;j<8;j++)
		wOLED_WriteData(my16x8[j + 8 * (i + 0ver*2)]);
	}
}

可以看出该函数是根据用户写入的Over参数,找到my16x8[数组中对应位置的字模数据将其读取出来,
并调用wOLED_WriteData(函数将数据发送给OLED。那么Over参数又该如何选取呢?
在每一个字模的最右侧都有一个标号,如字模0的标号是0。Over=标号

2.消除某一位置图像的方法
与写入图像信息类似,消除也是写入数据,不过写入的都是全空,由于消除的一般都是字模,
所以需要调用wShowOLED16X80函数。
wShowOLED16X8(1,50,30); //消 除百位
在字模库中可以找到全空的字模。
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" ",30
很多时候,我们需要对整个屏幕进行清除,这时侯可以调用wOLED_FullShow() 函数, 并将参数设为0x00即可。
wOLED_FullShow(0x00);

这样做有什么用处呢?
如果你想在OLED.上显示一个鼠标指针,那么指针移动的本质就是先将指针原先位置的图形.清除,再在新的位置写入一个指针图形。
如果你想将OLED的人机交互界面做得很有层次,毕竟屏幕大小有限,这时就可以使用先清屏再显示新界面的方法实现。

3.显示动画的方法
动画是有一帧一帧的图形动态显示形成的,这时每一帧图像的停留时间就显得很重要了。在这里可以直接调用wOLED_delay( )函数。
wOLED_delay(3E6); / /延时3秒
这种延时实际上是通过让处理器对一个数据不断自减实现的,经验测试,在60M 系统时钟下,每一次自减操作大概用时1微秒,当你想要延时一秒时,只需填入100000。 但这样看起来不够清晰,可以使用科学计数法1E6来代替。

4.从头到尾写入的原因
经实际测试,如每次仅对某几个点进行写操作,则会出现缺失“点”的现象,据推测这是OLED器件本身特性,即其适合整体连续的写操作。故这里采用了“从头到尾写入”的方法很好的解决了这个问题。如要求进度条实现“倒退”动画,则需要在写“从头到尾”操作前添加“清除整行”操作,即写入全0。这样做会出现一定的抖动现象,显示效果不是很平滑。工程案例源代码中保留了这一部分,可将其注释起来对比一下效果。.

三、测试指南

本文档配套有两个工程wOLED_S和wOLED_H,两者只有驱动方式不同,一个是用普通I/O口模拟SPI通信,另一个是用单片机自带的SPI模块进行通信。
1.软件模拟SPI通信
模块相关代码只在User_Component下的OLED文件中。
内容简单,可移植性好,使用方便。
2.硬件SPI驱动通信
模块相关代码主要在User_Component下的OLED文件中。
需要增加SPI模块的配置部分,较为复杂,可移植性不好。
将每一位数据的发送交给硬件处理,理论上能够降低处理器资源的占用。实际使用时需要增加延时环节,发送速度反而变慢。但减少了被中断干扰发送的概率。

两者的不同主要表现在wOLED_WriteData0和wOLED_WriteCommand()这两个函数和四个引脚的配置上。
综合以上分析,建议驱动OLED时采用模拟SPI通信的方式。

根据“模块及驱动简介”部分表格里引脚的对应关系用杜邦线将OLED模块和单片机连接起来。.
将工程导入CCS (v7及以上)中,编译运行无误后,Debug运行,观察案例效果。

(后面还有部分内容,下次再编辑发出来)

你可能感兴趣的:(IIC,OLED,单片机,嵌入式)