本节课将讲解如何基于CC2530来使用OLED显示屏来显示字符和图片。
视频讲解
https://www.bilibili.com/video/BV1k34y1D7Vz?p=18
OLED显示技术简介
(1)OLED的全称是Organic Light-Emitting Diode,也就是有机发光二尽管,具有自发光、广视角、高对比度和较低功耗等优点。
(2)开发套件里面配套的0.96寸OLED显示器的实物图如下图所示,它的分辨率是64×128像素,也就是纵向有64个像素点、横向有128个像素点。
(3)显示器的技术参数如下:
- 型号:0.96OLED12864
- 尺寸:0.96寸
- 像素:128×64
- 接口:SPI
- 针脚:GND、VCC、D0、D1、RES、DC和CS
SPI通信协议简介
SPI是一种跟UART类似的通信协议,它的全称是Serial Peripheral Interface,也就是串行外设接口,具有传输速度快、能够同时收发数据、发射端和接收端通信同步的特点。配套的OLED显示器用的就是SPI通信协议。字库与图库
为了使OLED屏幕能够正确地显示各种字符或图片,还需要先准备好一套字库和图库,例如标准ASCII字库、汉字字库和自主制作的图库等。OLED 驱动 API
为驱动OLED屏幕,笔者设计了相应驱动API供读者学习和使用。
OLED的驱动API可分为两个层次,分别是上层的OLED显示API和下层的SPI驱动API,驱动API还需要字库和图库文件配合工作。这3者在本实验代码中的如图所示位置。
OLED显示API简介
在配置好显示屏引脚和字库/图库文件后,调用OLED显示API即可在屏幕上显示指定的内容。打开OLED122864文件夹中的hal_oled12864.h文件,可以找到OLED显示API的定义代码:
//2. 51单片机入门/6. 显示器实验/Workspace/code/HW_LCD/HAL_OLED/hal_oled12864.h
/**
* @fn halOLED12864Init
*
* @brief 初始化OLED12864显示器,在使用屏幕前必须先调用
*/
void halOLED12864Init(void);
/**
* @fn halOLED12864ClearScreen
*
* @brief 清除屏幕上显示内容
*/
void halOLED12864ClearScreen(void);
/**
* @fn halOLED12864Show
*
* @brief 在屏幕上显示字符串,支持的字符格式:1. 8×16 ASCII码;2. 16×16 汉字
*
* @param line - 参数值范围:0 ~ 3
* @param column - 参数值范围:0 ~ 127
* @param str - 待显示的字符串
*
* @warning 16×16汉字
的字库需要先在此文件中定义FONT_TABLE_CHINESE_16×16
*/
void halOLED12864ShowX16(unsigned char line, unsigned char column, const unsigned char *str);
/**
* @fn halOLED12864ShowPicture
*
* @brief 在屏幕上显示图片
*
* @param x - 指定在横向从左边数起第x个像素开始显示图像,参数值范围:0 ~ 127
* @param y - 指定在纵向从上边数起的第y个像素开始显示图像,参数值范围:0 ~ 64
* @param picWidth - 图片的宽度,参数值范围:1~128
* @param picHeight - 图片的高度,参数值范围:1~64
* @param pic - 待显示的图片
*/
void halOLED12864ShowPicture(unsigned char x, unsigned char y, unsigned char picWidth, unsigned char picHeight, const unsigned char *pic);
halOLED12864ShowX16 使用详解
OLED12864显示屏的分辨率为64x128像素,可以把其理解为64行和128列的二维表格。halOLED12864ShowX16函数支持显示8×16的标准ASCII字符和16×16的汉字,其中的8×16是指占据屏幕8行、16列的字体,16×16是指占据屏幕16行和16列的字体。因此可以理解为halOLED12864ShowX16函数支持在屏幕中显示4行ASCII字符或汉字,于是参数line的取值范围便是0~3,但是参数column仍是使用像素点来表示在横向第几个像素的位置开始显示字符,因此其取值范围为0~127。
显示屏引脚配置
在调用上述显示API前,需要先进行显示屏引脚配置,即将显示屏的引脚与CC2530的GPIO配置上。配套的0.96英寸OLED显示屏包含如下7个引脚:
(1)GND - 地线
(2)VCC - 电源(2.8~5.5v)
(3)SCL(D0) - SPI时钟
(4)SDA(D1) - SPI数据
(5)CS - SPI片选
(6)RES - 屏幕复位引脚
(7)DC - 数据或命令选择
打开hal_lcd_spi.h文件,可以看到如下引脚配置代码。
//2.51单片机入门/6.显示器实验/Workspace/code/HW_LCD/HAL_LCD_SPI/hal_lcd_spi.h
#ifdef HAL_LCD_SPI_SW
/* SCL -> CC2530 P1_5 引脚*/
#define HAL_LCD_SPI_SCK_PORT 1
#define HAL_LCD_SPI_SCK_PIN 5
/* SDA -> CC2530 P1_6 引脚*/
#define HAL_LCD_SPI_SDA_PORT 1
#define HAL_LCD_SPI_SDA_PIN 6
#endif
/* CS -> CC2530 P2_0 引脚*/
#define HAL_LCD_SPI_CS_PORT 2
#define HAL_LCD_SPI_CS_PIN 0
/* DC -> CC2530 P1_4 引脚*/
#define HAL_LCD_SPI_DC_PORT 1
#define HAL_LCD_SPI_DC_PIN 4
/* RES -> CC2530 P1_0 引脚*/
#define HAL_LCD_SPI_RST_PORT 1
#define HAL_LCD_SPI_RST_PIN 0
上述代码完成了5个引脚的配置,其中的VCC和GND引脚不用配置。如果需要修改引脚配置,那么直接修改上述代码右边的数字即可。
配置字库
在配置好引脚后,还需配置字库和图库,其中字库包括两种,分别是8×16标准ASCII字库、16×16中文字库,字库文件在本实验代码如图所示位置。
在本课程配套的软件工具中,可以找到“字模软件2.2.zip”这个软件,它就是用来生成字库的。运行字模软件,如图所示。
如您还没有下载本课程配套的软件工具,可以前往下载页下载:前往
8×16标准ASCII字库取模取模步骤如下:
(1)单击“参数设置”→“其他选项”,依次选择“纵向取模”、“字节倒序”和“保留”,如图所示。
不同屏幕显示对字库的要求有所不同,配套的OLED显示屏要求“纵向取模”和“字节倒序”。
(2)在文字输入区输入想要取模的文字,输入后按一下Ctrl+Enter,如图所示。
(3)单击“取模方式”→“C51 格式”,选择“点阵生成区”,即可看到成功生成的字模,如图所示。
就这样,8×16字体对应的字库做好了。16×16汉字的取模方式与8×16字体基本一致,只需要依照相同的方式并且在输入区输入汉字即可。
配置图库
与自字体取模类似地,在基本操作处导入图片,然后参照字体取模流程操作即可完成图片的取模,如图所示。
使用OLED显示API
在配置好显示屏引脚和字库文件后,调用OLED显示API即可在屏幕上显示内容。打开配套的实验代码,打开OLED12864文件夹中的main.c,可以看到使用OLED显示API的示例代码:
//2. 51单片机入门/6. 显示器实验/Workspace/code/OLED12864/main.c
void main(void)
{
setSystemClk32MHZ();//把系统频率设置为32MHz
halOLED12864Init();//初始化
while(1)
{
/* Test1 - 显示 8×16 的字符 */
halOLED12864ShowX16(0, 0, "0123456789");//在第1行显示
halOLED12864ShowX16(1, 0, "abcdefghiABCDE");//在第2行显示
halOLED12864ShowX16(2, 0, "{}[]()!@#$%");//在第3行显示
halOLED12864ShowX16(3, 0, "==========>");//在第3行显示
delayMs(SYSCLK_32MHZ, 4000);//延迟
halOLED12864ClearScreen();//清空
/* Test2 - 显示 8×16 字符 和 16×16 汉字 */
halOLED12864ShowX16(0, 0, "今天气温:");
halOLED12864ShowX16(1, 30, "温度:22 ℃");
halOLED12864ShowX16(2, 30, "湿度:30 %");
/* 注意:对于汉字,必须先取字模后存放到汉字字库文件font_chinese_v_16x16.h中*/
delayMs(SYSCLK_32MHZ, 4000);//延迟
halOLED12864ClearScreen();//清空
/* Test3 - 在坐标(30像素, 30像素)处显示分辨率为 32x32 像素的图片*/
halOLED12864ShowPicture(30, 30, 32, 32, Picture_32x32_AppleIco);
/*注意:对于图片,系需要先取模后存放在图库文件font_v_picture.h中*/
delayMs(SYSCLK_32MHZ, 4000);//延迟
halOLED12864ClearScreen();//清空
/* Test4 - 全屏显示 128x64 图片,即在坐标(30像素, 30像素)处显示一张分辨率为128x64像素的图片 */
halOLED12864ShowPicture(0, 0, 128, 64, Picture_128x128_SuccessPic);
delayMs(SYSCLK_32MHZ, 4000);//延迟
halOLED12864ClearScreen();//清空
}
}
在实际的开发过程中,开发者一般只要套用上述代码即可使用OLED屏幕,非常方便。
SPI 驱动 API 的设计原理
SPI 驱动 API 的设计原理较为复杂,读者简单了解其原理即可。
上文讲到,笔者设计的OLED屏幕的驱动API可分为两个层次,分别是上层的OLED显示API和下层的SPI驱动API。这里简单地讲解一下本SPI驱动API的设计原理。
设计思想
笔者把SPI驱动API分为两个部分,分别是通用SPI驱动API和专用SPI驱动API。
(1)通用SPI驱动API适用于使用SPI通信的多种设备,图中的SPI_Driver文件夹存放的便是此部分API。
(2)专用SPI驱动API在通用SPI驱动API的基础上,专门去适配特定的设备,例如配套的这个OLED显示屏。图中的hal_lcd_spi.h和hal_lcd_spi.c便是此部分API
这样做的好处还是比较明显的,通用SPI驱动API可以在各种SPI设备中使用,只需要为这些设备增加对应的适配代码即可。
硬件和软件SPI模式的支持
在通用的SPI驱动API中,支持硬件SPI和软件SPI模式。硬件模式SPI是指利用利用硬件处理单元实现SPI协议,软件SPI模式是指通过编写程序代码的方式实现SPI。如图所示,hw_spi.h/c是基于硬件实现的SPI驱动API,sw_spi.h/c是软件模拟实现的SPI驱动API,如图所示。
可以在适配程序hal_lcd_spi.h和hal_lcd_spi.c中通过配置的方式来选择使用哪种方式,如图所示。
调试仿真
可以运行本实验代码以观察运行结果,操作步骤如下:
(1)把OLED屏幕插入到标准板或者Mini板中,如图所示。
(2)由于本实验需要用到SPI通信,因此如果使用ZigBee标准板测试,需要把拨码开关的第8、9和10位分别打到CLK、SDI和SDO端,如图所示。
(3)编译链接本实验代码后,把程序烧录到配套的ZigBee开发板中,即可看到屏幕循环地显示相应的内容。