OLED屏显示分析与实现

2023-09-14 12:27苏杰仁
现代信息科技 2023年13期
关键词:程序代码

摘  要:文章对OLED模块及其驱动芯片SSD1306、OLED的显示画面与显示存储器之间的关系、OLED写命令或写数据时序等进行了深入的研究与分析,揭示了OLED模块写命令或写数据的显示过程与工作原理,总结了OLED显示像素点的步骤,并根据所总结的步骤编写出显示程序代码,编译后把代码烧录到16位单片机STM32F103ZET6芯片上运行,成功实现OLED显示点线与汉字的功能,为后期深入图形显示以及其他类型显示屏的显示研究打下坚实的基础。

关键词:OLED;SSD1306;时序分析;程序代码;字符显示

中图分类号:TN383    文献标识码:A  文章编号:2096-4706(2023)13-0053-06

Analysis and Implementation of OLED Screen Display

SU Jieren

(Guangzhong Panyu Polytechnic, Guangzhou  511483, China)

Abstract: In this paper, a in-depth research and analysis on the OLED module and its driver chip SSD1306, the relationship between OLED display screen and display memory, OLED writing command or writing data timing is conducted. It reveals the display process and working principle of OLED module writing commands or writing data, summarizes the steps of OLED displaying pixels, and writes display program code based on the summarized steps. After compilation, the code is burned and run on the 16 bit Single-Chip Microcomputer STM32F103ZET6 chip, successfully achieving the function of OLED displaying dots, lines, and Chinese characters, laying a solid foundation for further research on graphic display and display other types of display screens.

Keywords: OLED; SSD1306; time series analysis; program code; character display

0  引  言

OLED是电子产品制作中较为常用的显示屏之一,其显示所用的驱动代码技术也相当稳定成熟,用户可以直接在网络上下载修改使用,但这样用户只是知道在OLED上如何显示出字符或图片,不能很好地理解OLED的工作原理及显示过程。本文深入浅出地介绍了OLED模块的写命令或写数据时序及其显示代码的编写过程,便于读者理解OLED的显示步骤和工作原理。

1  OLED屏介绍

OLED[1]即有机发光二极管,又称为有机电激光显示(Organic Electroluminescence Display),它具有自发光、对比度高、厚度薄、视角广、使用温度范围广、反应速度快等优点。它不需背光源,可用于挠曲性面板,是新一代平面显示器应用技术。

文章介绍的是I2C接口0.96英寸的OLED模块,各引脚接口说明如表1所示。模块的分辨率为128 × 64,具有并行6800、并行8080、串行SPI、串行I2C四种接口方式,可通过OLED模块上的BS1/BS2端口设置接口方式,当BS1设置为1,BS2设置为0时,OLED模块为I2C接口方式。

2  OLED驱动芯片SSD1306

OLED使用SSD1306芯片作为驱动[2]芯片,SSD1306的显存总共为128 × 64 bit大小,SSD1306将这些显存分成8页,每页包含128个字节,总共8页,刚好是128 × 64的点阵大小,如表2所示。

OLED模块的分辨率为128 × 64,屏幕的每个像素恰巧与SSD1306显存的点阵一一对应,往SSD1306的显存点阵写逻辑“1”,则OLED屏幕对应的像素点被点亮,OLED画面像素点与SSD13066儲存器点阵映射关系如图1所示。

MCU对OLED屏幕显示操作都是通过对SSD1306芯片进行写命令或写数据操作实现的,部分指令如表3所示。

如命令0x81,设置对比度,包含两个字节,第一个0x81为命令,随后发送的一个字节为要设置的对比度的值。这个值设置得越大屏幕就越亮。如命令0x8D,包含两个字节,第一个为命令字,第二个为设置值,第二个字节的BIT2表示电荷泵的开关状态,该位为1开启电荷泵,该位为0则关闭电荷泵。在模块初始化的时候,这个命令必须要开启,否则是看不到屏幕显示的。

对SSD1306芯片写命令或写数据操作,采用分割法进行分析,时序[3]如图2所示。

根据写命令或写数据操作特点绘制分割线,并在分割线处标记ABCDEFGHI,对标记点进行分析:

AB:S为IIC开始信号。

BC:IIC总线上设备的从地址位构成如图3所示,设置为0x78。

其中,R/W#表示读写选择位,R/W#设置为逻辑“0”时,主机发送命令或数据到IC,R/W#设置为逻辑“1”时,主机读取IC数据。SA0为从地址位,由SSD1306芯片D/C#引脚电平来决定,D/C#引脚接VCC时SA0=1,D/C#引脚接地时SA0=0。通常设置D/C#引脚接地,而MCU与驱动IC交互时,都是MCU发送命令或数据到IC,也就是只有写数据,没有读数据,所以R/W#设置为逻辑“0”,因此得到从机地址为01111000b,即0x78。

CD:IIC应答信号。

DE:控制字节位构成如图4所示,主要由Co和D/C#位组成,后跟六个“0”。

其中,Co表示连续设置位,设置为逻辑“0”时,传输的信息包含FG(Data byte)字节。D/C#位确定Data byte用作命令或数据。D/C#位设置为逻辑“0”时,将Data byte定义为命令。D/C#位设置为逻辑“1”时,则将Data byte定义为数据。若写命令,Control byte=00000000b,即0x00;若写数据,Control byte=01000000b,即0x40。

EF:答IIC应信号。

FG:命令或数据,由D/C#位决定。

GH:答IIC应信号。

HI:IIC结束信号。

注意:如需发送多个控制指令,则重复DH的操作。根据以上分析得出写命令与写数据函数[4]:

// 写命令函数

void Write_IIC_Command(unsigned char IIC_Command)

{

IIC_Start();          // AB:S为IIC开始信号

Write_IIC_Byte(0x78); //BC:从地址,SA0=0,R/W#=0

IIC_Ack();            // CD:IIC应答信号

Write_IIC_Byte(0x00); // Co=0,D/C#=0,写命令

IIC_Ack();            //EF:IIC应答信号。

Write_IIC_Byte(IIC_Command);  // FG:命令

IIC_Ack();            //GH:IIC应答信号。

IIC_Stop();           //HI:IIC结束信号

}

// 写数据函数

void Write_IIC_Command(unsigned char IIC_Data)

{

IIC_Start();          // AB:S为IIC开始信号

Write_IIC_Byte(0x78); //BC:从地址,SA0=0,R/W#=0

IIC_Ack();            // CD:IIC应答信号

Write_IIC_Byte(0x40); // Co=0,D/C#=1,写数据

IIC_Ack();            //EF:IIC应答信号。

Write_IIC_Byte(IIC_Data);  // FG:数据

IIC_Ack();           //GH:IIC应答信号。

IIC_Stop();           //HI:IIC结束信号

}

3  OLED显示分析

OLED显示字符[5]过程分为以下三步:

1)OLED初始化。

2)写入显示的地址。

3)写入显示的内容。

3.1  OLED初始化

OLED的初始化在模块设计时已经规定好,只需MCU向OLED模块发送相关的指令即可完成,过程如下:

Write_IIC_Cmd(0xae);//關闭显示

Write_IIC_Cmd(0x00);//设置列低地址

Write_IIC_Cmd(0x10);//设置高低地址

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

Write_IIC_Cmd(0xb0);//设置页寻址模式页面起始地址

Write_IIC_Cmd(0x81);//设置对比度

Write_IIC_Cmd(0xff);

Write_IIC_Cmd(0xa1);//设置段重新映射

Write_IIC_Cmd(0xa6);//设置正常显示

Write_IIC_Cmd(0x3f);

Write_IIC_Cmd(0xc8);//设置COM输出扫描方向

Write_IIC_Cmd(0xd3);//设置显示偏移

Write_IIC_Cmd(0x00);

Write_IIC_Cmd(0xd5);//设置时钟分频比/振荡器频率

Write_IIC_Cmd(0xf0);

Write_IIC_Cmd(0xd9);//设置预充电周期

Write_IIC_Cmd(0x22);

Write_IIC_Cmd(0xda);//设置COM引脚硬件配置

Write_IIC_Cmd(0x02);//设置为页寻址模式

Write_IIC_Cmd(0xdb);//设置VCOMH取消选择级别

Write_IIC_Cmd(0x49);

Write_IIC_Cmd(0x8d);

Write_IIC_Cmd(0x14);

Write_IIC_Cmd(0xaf);//设置显示器开

Oled_Clear();//清屏

3.2  写入显示的地址

根据SSD1306显存点阵特点,若要确定OLED显示的地址,需要通过确定寻址模式、确定第几个PAGE、确定第几列三个步骤[6]来完成。

SSD1306有128×64个点,在SSD1306显存写入逻辑“1”就可以点亮对应OLED屏幕上的点。但是对SSD1306显存写入逻辑“1”的顺序是怎样的呢?根据手册分析SSD1306显存写入逻辑“1”模式有三种:页寻址模式、水平寻址模式、垂直寻址模式,如图5所示。

所以,三个步骤如下:

1)确定OELD的写入模式为页寻址模式,通过Addressing SetingCommand Table中的A[1:0]位设置完成,其中A[1:0]=00b为水平寻址模式,A[1:0]=01b为垂直寻址模式,A[1:0]=10b为页寻址模式,如表4所示。

设置如下:

Oled_Write_Cmd(0x20);

Oled_Write_Cmd(0x02); //设置为页寻址模式

2)确定是第几个PAGE,通过Addressing SetingCommand Table中的B[7:0]的低3位X2 X1 X0设置完成,X2 X1 X0取000~111值,对应为0~7页,如表5所示。

设置如下:

Oled_Write_Cmd(0xb0+i),其中i的取值范围为0~7,i为0时对应的是第0页。

3)确定0~127列中的第几列,分别通过Addressing SetingCommand Table中的00~0F、10~1F的低4位设置完成,如表6所示。

設置如下:

Oled_Write_Cmd(0x00);// 设置8位起始列地址的低四位,列地址在每个数据接收后自加1。

Oled_Write_Cmd(0x10);// 设置8位起始列地址的高四位,列地址在每个数据接收后自加1。

3.3  写入数据(点或线)

经过前面的准备,接下来只需调用写数据函数给OLED写入显示的数据即可点亮屏幕上对应的像素点。程序如下:

Oled_Write_Data(0x00);// 0000 0000, 无显示

Oled_Write_Data(0xff);// 1111 1111, 显示一条线

4  实验结果

程序经过编译后烧录到STM32F103ZET6 [7]芯片运行后,可见OLED屏幕显示一条线,效果如图6所示。如需显示文字则通过取模软件把文字生成代码,再把代码写到OLED的显存里即可显示出对应的文字了。如显示“番”字[8],通过PCtoLCD2002软件取模[9],如图7所示,得到“番”代码如下:

char zifu[2][16]={{0x20,0x20,0x22,0xA6,0x6A,0x22,0x22,0x7E,0x21,0x21,0x69,0xA5,0x21,0x20,0x20,0x00},{0x02,0x02,0x01,0xFF,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0xFF,0x01,0x02,0x02,0x00}};

由于一个汉字为2个字节[10]长度,即16位长度,而SSD1306显存1页才1个字节长度,即8位长度,因此需要将汉字拆成上下两个部分,汉字上部分代码写入显存的第1页,下部分代码写入显存的第2页,从而凑成了一个完整的汉字。

程序如下:

Write_IIC_Cmd(0xb0+0);//确定第0页

Write_IIC_Cmd(0x00);//设置列低地址

Write_IIC_Cmd(0x10);//设置列高地址

for(i=0;i<16;i++) Write_IIC_Data(zifu[0][i]);

//写第1页数据

Write_IIC_Cmd(0xb0+1); //确定第1页

Write_IIC_Cmd(0x00);//设置列低地址

Write_IIC_Cmd(0x10);//设置列高地址

for(i=0;i<16;i++) Write_IIC_Data(zifu[1][i]);

//写第2页数据,

程序编译烧录后系统运行“番”字,显示效果如图8所示。其他文字、图形与“番”字的显示过程一样,同样需要通过字符取模软件生成代码后写到OLED的显存里才能显示。

5  结  论

本文实现了OLED显示点线与汉字的功能,验证了SSD1306时序分析的分割法、OLED显示像素点三步骤的可行性,读者可以借鉴此方法与步骤分析其他类型显示屏的显示原理。尚待解决的问题是没有对OLED显示屏的显示坐标位置与显示数据的关系进行深入分析,没有写出显示坐标位置与显示数据的具体函数。

参考文献:

[1] 王红敏,王燕,刘军强,等.基于Arduino控制的OLED显示模块的电子实践教学研究 [J].高教学刊,2021,161(3):7-11.

[2] 任克强,王传强.基于STC8F1K08S2的串口驱动OLED显示系统设计 [J].电子器件,2022,45(1):40-44.

[3] 张艳秋.F2812与外设之间的时序分析 [J].计测技术,2017,37(S1):277-280.

[4] 刘林芳.嵌入式系统中C语言编程软件设计 [J].电子技术与软件工程,2021,195(1):24-25.

[5] 苏杰仁.字符型LCD1602显示分析与实 [J].科技资讯,2022,20(22):9-12+160.

[6] 肖文文,胡平平.OLED字符显示和图形绘制系统的设计与实现 [J].北京信息科技大学学报:自然科学版,2011,26(6):70-75.

[7] 曾一凡,杨振南,王亚勇.基于STM32的智能物料搬运机器人的设计 [J].儀器仪表用户,2023,30(1):9-12.

[8] 赵华峰.LCD1602模块的汉字显示研究 [J].现代信息科技,2020,4(17):35-37.

[9] 王海梅.取模软件在LED显示屏设计中的使用与分析 [J].科技信息,2014,463(6):54.

[10] 陈一鸣.基于51单片机的图形液晶显示器汉字显示方法分析 [J].自动化与仪器仪表,2011,158(6):70-71+75.

作者简介:苏杰仁(1981—),男,汉族,广东肇庆人,讲师,硕士研究生,主要研究方向:智能产品开发。

收稿日期:2023-02-06

基金项目:广州市职业院校教师教学创新团队项目(2022JSJXCXTD001)

猜你喜欢
程序代码
AutoCAD三维实体转二维视图方法的研讨
MATLAB在定积分教学中的应用研究
借助脚本管理网络设备
浅谈专利审查中程序代码的审查技巧
计算机网络信息安全未来发展趋势
基于图元装接模式由程序流程图自动生成源代码
基于AutoCAD的多段线点坐标提取
DiGiCo SD系列数字调音台将迎来升级
一种可在线更新程序的DSP自举模块※
基于MATLAB GUI实现图像阈值分割处理的方法