STM32F103基于SPI的OLED显示

您所在的位置:网站首页 oled显示模块原理 STM32F103基于SPI的OLED显示

STM32F103基于SPI的OLED显示

2023-09-05 15:07| 来源: 网络整理| 查看: 265

目录 一、SPI协议1.1 什么是SPI协议1.2 SPI 协议的物理层1.3 SPI 协议的协议层1.4 SPI工作模式1.5 SPI 优缺点 二、0.96寸OLED屏2.1 简介2.2 接口定义2.3 引脚接线2.4 点阵编码原理与显示 三、使用OLED屏显示数据3.1 程序下载3.2 工程文件3.3 字模提取3.4 修改代码3.5 程序烧录 四、使用OLED屏滑动文字4.1 OLED屏的滚屏命令a. 禁用滚动(2Eh)b. 启用滚动(2Fh)c. 设置水平左右滚动d. 设置垂直和水平滚动 4.2 修改代码4.3 结果显示 五、总结六、参考资料

一、SPI协议 1.1 什么是SPI协议

SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。 它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率较高的场合。

SPI总线系统可直接与各个厂家生产的多种标准外围器件连接,该接口一般使用4条线:

串行时钟线(SCK)主机输入/从机输出数据线MISO主机输出/从机输入数据线MOST低电平有效的从机选择线C/S(有的SPI接口芯片带有中断信号线INT或INT、有的SPI接口芯片没有主机输出/从机输入数据线MOSI)。 1.2 SPI 协议的物理层

SPI 通讯设备之间的常用连接方式如下: 在这里插入图片描述 SPI 通讯使用 3 条总线及片选线,3 条总线分别为 SCK、MOSI、MISO,片选线为SS。

SS(Slave Select):从设备选择信号线,常称为片选信号线,也称为 NSS、CS。 当有多个 SPI 从设备与 SPI 主机相连时,设备的其它信号线 SCK、MOSI 及 MISO 同时并联到相同的 SPI 总线上,即无论有多少个从设备,都共同只使用这 3 条总线;而每个从设备都有独立的这一条 NSS 信号线,本信号线独占主机的一个引脚,即有多少个从备,就有多少条片选信号线。 SPI 通讯以 NSS 线置低电平为开始信号,以 NSS 线被拉高作为结束信号。

SCK (Serial Clock):时钟信号线,用于通讯数据同步。 它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如 STM32 的 SPI 时钟频率最大为fpclk/2,两个设备之间通讯时,通讯速率受限于低速设备。

MOSI (Master Output, Slave Input):主设备输出/从设备输入引脚。 主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。

④MISO(Master Input,,Slave Output):主设备输入/从设备输出引脚。 主机从这条信号线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。

1.3 SPI 协议的协议层

SPI 协议定义了通讯的起始和停止信号、数据有效性、时钟同步等环节。 SPI 基本通讯过程如下图: 在这里插入图片描述

这是一个主机的通讯时序。NSS、SCK、MOSI 信号都由主机控制产生,而 MISO 的信号由从机产生,主机通过该信号线读取从机的数据。MOSI 与 MISO 的信号只在 NSS 为低电平的时候才有效,在 SCK 的每个时钟周期 MOSI 和 MISO 传输一位数据。

1.4 SPI工作模式

根据 CPOL 及 CPHA 的不同状态,SPI 分成了四种模式如下图所示,主机与从机需要工作在相同的模式下才可以正常通讯,实际中采用较多的是模式 0与模式 3。 在这里插入图片描述

1.5 SPI 优缺点

优点 a) 支持全双工通信 b) 通信简单 c) 数据传输速率块

缺点 a) 没有指定的流控制,没有应答机制确认是否接收到数据,所以跟IIC总线协议比较在数据 b) 可靠性上有一定的缺陷。

二、0.96寸OLED屏

这里以7针SPI通信方式的OLED为例进行说明 具体产品介绍:0.96inch SPI OLED Module

2.1 简介

OLED(OrganicLight-Emitting Diode),又称为有机电激光显示、有机发光半导体(OrganicElectroluminesence Display,OLED); OLED属于一种电流型的有机发光器件,是通过载流子的注入和复合而致发光的现象,发光强度与注入的电流成正比,有如下特点:

0.96寸OLED屏,支持黑白、黑蓝或者黄蓝双色显示128x64分辨率,显示效果清晰,对比度高超大可视角度:大于160°(显示屏中可视角度最大的一种屏幕)宽电压供电(3V~5V),兼容3.3V和5V逻辑电平,无需电平转换芯片默认为4线制SPI总线,可以选择3线制SPI总线或者IIC总线超低功耗:正常显示仅为0.06W(远低于TFT显示屏)提供丰富的STM32、C51、Arduino、Raspberry Pi以及MSP430平台示例程序提供底层驱动技术支持 2.2 接口定义

产品如下图所示: 在这里插入图片描述

该模块支持IIC、3线制SPI以及4线制SPI接口总线模式切换(如图2红框内所示),具体说明如下: a、使用4.7K电阻只焊接R3、R4,则选择4线制SPI总线接口(默认); b、使用4.7K电阻只焊接R2、R3,则选择3线制SPI总线接口; c、使用4.7K电阻只焊接R1、R4、R6、R7、R8,则选择IIC总线接口;

接口总线模式切换后,需要选择相应配套的软件和相应的接线引脚(如图1所示),模块才能正常运行。相应的接线引脚说明如下: a、选择4线制SPI总线接口,所有的引脚都需要使用; b、选择3线制SPI总线接口,只有DC引脚不需要使用(可以不接),其他引脚都需要使用; c、选择IIC总线接口,只需要使用GND、VCC、D0、D1这四个引脚,同时将RES接高电平(可以接VCC),DC和CS接电源地;

在这里插入图片描述

2.3 引脚接线 模块引脚STM32开发板GNDGNDVCC3.3V/5VD0PB13D1PB15RESPB12DCPB10CSPB11 2.4 点阵编码原理与显示 汉字点阵编码 在汉字的点阵字库中,每个字节的每个位都代表一个汉字的一个点,每个汉字都是由一个矩形的点阵组成,0 代表没有点,1 代表有点,将 0 和 1 分别用不同颜色画出,就形成了一个汉字,常用的点阵矩阵有 1212, 1414, 16*16 三 种字库。 字库根据字节所表示点的不同有分为横向矩阵和纵向矩阵,目前多数的字库都是横向矩阵的存储方式(用得最多的应该是早期 UCDOS 字库),纵向矩阵一 般是因为有某些液晶是采用纵向扫描显示法,为了提高显示速度,于是便把字库 矩阵做成纵向,省得在显示时还要做矩阵转换。OLED点阵显示 点阵屏像素按128列X64行组织,每一行128个像素单元的阴极是连接在一起,作为公共极(COM),每一列64个像素单元的阳极也连接在一起,作为一段(SEG)。行列交叉点上的LED就是一个显示单元,即一个像素。要点亮一个像素,只要在该像素所在列电极上加上正电压、行电极接地。同样,要驱动一整行图像,就需要同时把128列信号加载到列电极上,把该行行电极接地。该行显示时,其他63行均不能显示,其行电极应为高电平或悬空。 可见,整屏的显示,只能分时扫描进行,一行一行的显示,每次显示一行。行驱依次产生低电平扫描各行,列驱动读取显示数据依次加载到列电极上。扫描一行的时间称为行周期,完成一次全屏扫描,就叫做一帧。一般帧频大于60,人眼观察不到逐行显示。每行扫描显示用时叫占空比,占空比小,为达到相同的显示亮度,驱动电流就大。SSD1306段驱动最大电流为100uA,当整行128个像素全部点亮时,行电极就要流过12.8mA的电流。 三、使用OLED屏显示数据 3.1 程序下载

商家给出的demo下载链接:0.96寸SPI_OLED模块配套资料包 具体内容如下: 在这里插入图片描述

3.2 工程文件

打开资料包中的Demo,用keil软件打开与自己平台相同的工程实例,我这里使用的是STM32F103RCT6 在这里插入图片描述 每个子文件的最上方都有给出具体引脚接线说明: 在这里插入图片描述 在spi.c查看OLED的SPI通信协议程序 在这里插入图片描述

3.3 字模提取

由于程序并不能显示所有的中文汉字,所以首先要对显示的汉字进行取模,再添加到程序中。

进入汉字字模提取网页版:LCD/OLED汉字字模提取软件 修改取模方式为横向8点左高位,字体种类为[HZK1616宋体] 在这里插入图片描述 输入要取模的汉字,点击取模得到汉字的点阵; 在这里插入图片描述 3.4 修改代码

进入工程,在USER文件夹下打开gui.c,在include包含的头文件中右击可打开oledfont.h在这里插入图片描述

在函数const typFNT_GB16 cfont16[]中插入刚才所获取的点阵字模

"通",0x03,0xF8,0x40,0x10,0x30,0xA0,0x10,0x48,0x03,0xFC,0x02,0x48,0xF2,0x48,0x13,0xF8, 0x12,0x48,0x12,0x48,0x13,0xF8,0x12,0x48,0x12,0x68,0x2A,0x50,0x44,0x06,0x03,0xFC, "信",0x08,0x80,0x08,0x44,0x0F,0xFE,0x10,0x00,0x10,0x08,0x37,0xFC,0x50,0x00,0x90,0x08, 0x17,0xFC,0x10,0x00,0x13,0xF8,0x12,0x08,0x12,0x08,0x12,0x08,0x13,0xF8,0x12,0x08, "一",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xFF,0xFE, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, "班",0x01,0x00,0x09,0x04,0xFD,0x7E,0x21,0x10,0x25,0x10,0x25,0x10,0x25,0x10,0xF5,0x7C, 0x25,0x10,0x29,0x10,0x21,0x10,0x22,0x10,0x3A,0x10,0xE2,0x14,0x44,0xFE,0x08,0x00

在这里插入图片描述

在test.c文件中,修改TEST_MainPage函数: void TEST_MainPage(void) { GUI_ShowString(28,0,"sapphire",16,1); //显示英文字符串 GUI_ShowCHinese(28,20,16,"通信一班",1); //显示中文汉字 GUI_ShowString(4,48,"631907030132",16,1); //显示数字 delay_ms(1500); delay_ms(1500); }

函数说明— GUI_ShowString() 的参数 参数一:X 坐标 参数二:Y 坐标 参数三:字符串(ASCLL码中的) 参数四:bit(表示字符显示格式,这里我用的 16 ,和汉字一样高) 参数五:显示样式(1:白字黑底;0:黑字白底) GUI_ShowChinese() 的参数 参数一:X 坐标 参数二:Y 坐标 参数三:汉字点阵大小(这里使用的是 16×16 的,参数应该是 16) 参数四:要显示的汉字 参数五:显示样式(1:白字黑底;0:黑字白底)

在这里插入图片描述

main()函数 int main(void) { delay_init(); //延时函数初始化 NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 OLED_Init(); //初始化OLED OLED_Clear(0); //清屏(全黑) while(1) { TEST_MainPage(); //主界面显示测试 } } 3.5 程序烧录

打开mcuisp软件选择.hex文件烧录 在这里插入图片描述 结果显示: 在这里插入图片描述

四、使用OLED屏滑动文字 4.1 OLED屏的滚屏命令 a. 禁用滚动(2Eh)

此指令用于停止滚动,在调用命令2Eh后,RAM的数据需要被重写

b. 启用滚动(2Fh)

此指令用于启动滚动,并且只能在滚动配置参数经过调用命令26h/27h/29h/2Ah后调用。最后调用滚动参数命令时的配置将覆盖之间调用过时设置的配置

以下操作会在启用滚动后被禁止:

对RAM的访问改变水平滚动配置参数 c. 设置水平左右滚动

代码:

OLED_WR_Byte(0x2E,OLED_CMD); //关闭滚动 OLED_WR_Byte(0x26,OLED_CMD); //水平向左或者右滚动 26/27 OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节 OLED_WR_Byte(0x00,OLED_CMD); //起始页 0 OLED_WR_Byte(0x07,OLED_CMD); //滚动时间间隔 OLED_WR_Byte(0x07,OLED_CMD); //终止页 7 OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节 OLED_WR_Byte(0xFF,OLED_CMD); //虚拟字节 OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动

注意 :设置水平滚动需要在调用前关闭滚动, 否则RAM中的内容将会出错 ,还有的是在写入终止页后需要写入两个虚拟字节,网上说有些是不需要写入这两个虚拟字节,可能因为厂家不同吧,所以设置不成功的小伙伴可以试试是不是这里出了问题!!!

d. 设置垂直和水平滚动

代码:

OLED_WR_Byte(0x2e,OLED_CMD); //关闭滚动 OLED_WR_Byte(0x29,OLED_CMD); //水平垂直和水平滚动左右 29/2a OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节 OLED_WR_Byte(0x00,OLED_CMD); //起始页 0 OLED_WR_Byte(0x07,OLED_CMD); //滚动时间间隔 OLED_WR_Byte(0x07,OLED_CMD); //终止页 1 OLED_WR_Byte(0x01,OLED_CMD); //垂直滚动偏移量 OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动

注意:垂直滚动偏移量=0时,就只有水平左右移了。通过设置起始页、终止页,被设置的区域就可以垂直和水平滚动,其余的区域就只有垂直滚动。

更多详细命令的了解,请查找SSD1306-OLED驱动中文手册或者参考链接:SSD1306(OLED驱动芯片)指令详解

4.2 修改代码 修改 TEST_MainPage函数 void TEST_MainPage(void) { GUI_ShowCHinese(0,16,16,"黄昏跟清晨",1); //显示中文汉字 GUI_ShowCHinese(0,35,16,"无法相认",1); //显示中文汉字 delay_ms(1500); delay_ms(1500); } 修改main函数 int main(void) { delay_init(); //延时函数初始化 NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 OLED_Init(); //初始化OLED OLED_Clear(0); //清屏(全黑) OLED_WR_Byte(0x2E,OLED_CMD); //关闭滚动 OLED_WR_Byte(0x27,OLED_CMD); //水平向左或者右滚动 26/27 OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节 OLED_WR_Byte(0x00,OLED_CMD); //起始页 0 OLED_WR_Byte(0x07,OLED_CMD); //滚动时间间隔 OLED_WR_Byte(0x07,OLED_CMD); //终止页 7 OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节 OLED_WR_Byte(0xFF,OLED_CMD); //虚拟字节 TEST_MainPage(); OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动 while(1) {} } 4.3 结果显示

将程序烧录进开发板后,效果如下所示: 在这里插入图片描述

五、总结

本次实验通过理解OLED屏显和汉字点阵编码原理,及stm的SPI协议,将程序烧录进stm32的开发板,完成了在OLED屏上的显示及滚动显示。其实实际的操作过程并不难,只需要修改demo代码再接入开发板中,OLED显示屏显示汉字的也是通过点阵实现的。

六、参考资料 https://blog.csdn.net/qq_54496810/article/details/121434661https://blog.csdn.net/qq_45237293/article/details/111712565https://blog.csdn.net/qq_54496810/article/details/121434661


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3