基于STC8F1K08S2 的串口驱动OLED 显示系统设计*
2022-06-02任克强王传强
任克强,王传强
(江西理工大学信息工程学院,江西 赣州 341000)
常用的显示屏有LED、LCD、OLED 等[1-2],小型OLED 屏幕以其显示效果好、显示质量优、价格便宜等特点,被广泛地应用在小型嵌入式系统、单片机系统、电子产品等领域[3-5]。OLED 屏幕的驱动方式主要有8080 并口、IIC、SPI 等驱动方式[6-8]。对于8080 并口驱动方式,可使用高端处理器模拟8080接口时序或者使用带有FSMC 接口的处理器完成驱动;对于IIC 和SPI 驱动方式,一些低端的处理器通过模拟时序也可以实现OLED 屏幕的驱动,但增加了处理器的负担,并且OLED 屏幕显示的字符、汉字、图片等信息都需要取模后写入到内部程序存储器中,需占用大量的内存空间,对于内存较小的处理器,很容易被占满,导致处理器无法处理其他任务[9-10]。
针对上述问题,本文设计了一种串口控制的小型OLED 屏幕驱动显示系统。该系统采用了低成本的MCU 方案,外扩FLASH 存储器用于存储16×16、24×24、32×32 三种尺寸的GB2312 中文字库[11];系统通过串口通道完成与外界的数据交换,实现OLED 屏幕上数字、字符、汉字、图像等信息的显示;因此只需要具有串口功能的处理器或者通过IO 口模拟串口功能即可使用该系统,从而使得OLED 屏幕的使用得到简化,一般的处理器均可使用OLED屏幕,扩展了OLED 屏幕的适应性和应用范围。
1 系统硬件设计
本文设计的OLED 驱动显示系统主要由OLED屏幕、接口转换电路、STC8F1K08S2 处理器和W25Q16 FLASH 存储器组成。系统硬件组成如图1所示。
图1 系统硬件框图
本文使用的STC8F1K08S2 处理器采用SOP16封装,体积小,易于嵌入,不需要配合任何外围电路即可使用;内置晶振,频率可选,最小5.529 6 MHz,最大27 MHz,本文选用22.118 4 MHz;处理器有14个IO 接口,内置硬件SPI 电路,并使用内置SPI 实现W25Q16 数据读写。本文将OLED 屏幕通过硬件接口转换为SPI 驱动接口,并使用处理器IO 模拟SPI 时序实现对OLED 的驱动,之所以没有使用硬件SPI,主要是避免2 个SPI 器件在驱动中互相影响。
W25Q16 内部Block 的内存划分如表1 所示。
表1 W25Q16 内部Block 划分
W25Q16 具有2 Mbyte 的FLASH 存储空间,划分为32 个Block,每个Block 有64 kbyte 空间[12]。在这些空间存储了3 种尺寸 GB2312 字库:256 kbyte 的16×16 尺寸字库、576 kbyte 的24×24 尺寸字库、1 024 kbyte 的32×32 尺寸字库。字库在FLASH 中地址分配如表2 所示,根据字库的存储地址和字库尺寸,可以计算出不同字的偏移地址,根据偏移地址可以读取字库数据进行显示。
表2 字库在FLASH 中地址分配
小型OLED 屏幕有0.42、0.49、0.91、0.96、1.3 寸等多种不同尺寸,都可以通过硬件转换成SPI 驱动方式与本系统连接。对于不同驱动IC 的OLED 屏幕,主要是屏幕的初始化不同,上层对屏幕的各种操作是相同的,因此可以根据不同驱动IC 调用不同初始化函数即可。本文采用0.96 寸驱动IC 为SSD1306 和1.3 寸驱动IC 为SH1106 两种OLED 进行驱动测试。
2 系统软件设计
系统软件流程如图2 所示。首先对系统和各个模块进行初始化操作,打开串口接收中断,然后进入系统控制部分,等待外部处理器发来的设置波特率指令,串口波特率控制指令如表3 所示,可通过发送对应的控制指令改变系统的波特率,从而可以适应不同性能的处理器,波特率设置完成后,将该波特率保存并覆盖原有的默认波特率,系统初始默认波特率为9 600 bit/s。为了防止用户设置外部处理器波特率出现不一致情况,在OLED 上电后会在屏幕显示5 s 当前波特率。设置完波特率,等待串口接收来自外部的数据显示和设置坐标指令:0x01 代表接收数字数据,0x02 代表接收字符或者汉字数据,0x03 代表接收图像数据;坐标轴为X轴和Y轴,X轴范围0~127,Y轴范围为0~7。通过指令对系统设置后,就开始接收来自外部处理器发来的数据,驱动OLED 显示相应的内容。
表3 串口波特率控制指令
图2 系统软件流程图
2.1 FLASH 字库读写
通过串口将字库文件写入W25Q16 FLASH 中,为了准确判断字库文件是否成功地写入到FLASH中,首先获取各尺寸字库的结束地址(即尾地址),然后根据尾地址和存储在W25Q16 中的首地址进行计算可得各尺寸字库在W25Q16 中的尾地址,字库尾地址如表4 所示。在写入过程中,串口每接收到一个数据,地址自动加1,通过地址对比,就可判断字库文件是否成功写入。字库写入程序流程如图3 所示,三种尺寸的字库依次写入,首先写入16×16 的,从W25Q16 的0 地址开始写,每写入1 byte,地址数据加1,直到地址等于0x03FE41 完成16×16 字库的写入;然后设置偏移地址为 0x040000,并从0x040000 开始写入24×24 字库,每写1 byte 地址加1,直到地址等于0x0CFC11 完成24×24 字库写入;最后设置偏移地址为0x0D0000,并从0x0D0000 开始写入32×32 字库,每写1 byte 地址加1,直到地址等于0x1CF901 完成32×32 字库写入。
表4 字库尾地址
图3 字库写入程序流程图
在GB2312 中将汉字划分为94 个区,每个区有94 个位,即区和位。通过汉字的区和位就可以确定一个汉字在字库中的偏移地址,然后就可以确定汉字的点阵数据。一个汉字是由两个扩展的ASCII 码表示,一个用来存放区码,另一个用来存放位码,也可以说汉字的高字节和低字节,并且在区码和位码上分别加上了32,因此可以通过式(1)、式(2)求出汉字的区码和位码。
计算出区码和位码,根据式(3)可获取汉字在字库中的偏移地址,然后通过访问该偏移地址,即可获取该地址中存放的汉字点阵数据。
2.2 OLED 显示驱动
OLED 采用模拟4 线SPI 的方式进行驱动,驱动时序如图4 所示。CS 在低电平时,芯片被选中,开始数据通信,在SCLK 低电平时,SDIN 作为信号线,而在每个SCLK 的上升沿,SDIN 会发出1 bit 数据,在每个周期发送8 bit 的数据,然后CS 拉高,完成一次数据通信。
图4 OLED 4 线SPI 驱动时序
整个OLED 上层驱动主要包括波特率修改函数、显示选择函数、坐标定位函数、字体选择函数、数字显示函数、字符汉字显示函数、图像显示函数。上述函数的数据均读取自串口接收的数据。由于GB2312 中的每个字符都占有2 byte,因此对于单字节的字符可调用处理器内部的取模数据,汉字调用外部FLASH 字库数据。
3 系统测试
在硬件方面,整个系统与市场上较流行的小型OLED 模块相差无几,两者对比如图5 所示,左边为本文设计制作的OLED 驱动系统,右边为市场上较流行的小型OLED 模块。
图5 OLED 模块对比图
为了测试本文设计的小型OLED 屏幕驱动显示系统的性能,通过控制OLED 驱动显示,并调整不同的波特率,对数字、字符、汉字、图像进行测试。
通过设定不同的坐标值,将不同尺寸的数字、字符、汉字进行显示,显示测试结果如图6 所示。通过测试,整体显示效果流畅,汉字、字符、数字能准确识别,显示无乱码现象,显示位置可任意设置。
图6 不同尺寸字体显示测试
对图像显示进行测试,将一幅图像完整显示在屏幕上,测试结果如图7 所示。显示一张图片,一次读取的数据较多,由于不同波特率下数据读取速率不同,因此图片显示的流畅度存在差异,在9 600 bit/s及以上波特率显示效果较为流畅,刷新速率较快。在9 600 bit/s 以下波特率,显示刷新速度较慢,在对速度要求不高的低端处理器可使用。
图7 图像显示测试
4 结论
OLED 屏幕被广泛地应用在小型嵌入式系统、单片机系统、电子产品等,但OLED 屏幕的显示内容需采用取字模的方式,很容易使得内存被占满或溢出,并且OLED 屏幕的驱动也具有一定的复杂度。为方便用户使用OLED 屏幕,本文采用MCU 控制方案,外加FLASH 芯片,通过串口对OLED 屏幕进行控制;可使用多种处理器通过串口或者模拟串口的方式进行OLED 屏幕驱动;本系统加入了3 种汉字字库,大量节约了处理器的程序存储空间;所有驱动都已载入本系统,用户不需考虑OLED 屏幕的驱动问题,只需通过串口发送指令数据即可完成驱动,简化了OLED 屏幕的驱动使用。针对不同性能的处理器,可调节波特率,以适应不同处理器性能。由于使用串口通信,也可以使用蓝牙等串口无线通信模块,进行无线数据传输,拓展了OLED 的应用场景和适应范围。经测试整个系统运行稳定可靠,可在不同波特率下正确接收串口指令和数据,能够正常显示数字、字符、汉字和图像,显示效果流畅,能够较好地满足各种OLED 屏幕的显示需求。