STM32F103基于SPI的OLED显示

一、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。

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

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

  3. 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 优缺点

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

  2. 缺点
    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开发板
GNDGND
VCC3.3V/5V
D0PB13
D1PB15
RESPB12
DCPB10
CSPB11

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 修改代码

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

  2. 在函数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

在这里插入图片描述

  1. 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:黑字白底)

在这里插入图片描述

  1. 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 修改代码

  1. 修改 TEST_MainPage函数
void TEST_MainPage(void)
{	
	GUI_ShowCHinese(0,16,16,"黄昏跟清晨",1);	//显示中文汉字
	GUI_ShowCHinese(0,35,16,"无法相认",1);	//显示中文汉字
	delay_ms(1500);		
	delay_ms(1500);
}
  1. 修改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显示屏显示汉字的也是通过点阵实现的。

六、参考资料

  1. https://blog.csdn.net/qq_54496810/article/details/121434661
  2. https://blog.csdn.net/qq_45237293/article/details/111712565
  3. https://blog.csdn.net/qq_54496810/article/details/121434661
  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32F103是一款常用的ARM Cortex-M3系列的单片机,通过SPI接口来实现与外部设备的通信是常见的应用之一。以下是关于如何使用STM32F103SPI接口来读写OLED显示屏的简要概述。 首先,确保已经按照需要的电气连接,将OLED显示屏与STM32F103连接起来,其中包括SCK、MOSI、CS(片选)以及DC(数据/命令切换)等信号线。 其次,配置SPI接口。首先,使能SPI时钟,选择合适的SPI通道,配置SPI模式以及时钟分频等参数。可以使用STM32CubeMX工具来简化配置过程。然后,根据OLED显示屏的规格,配置SPI通信的特殊需求,如数据宽度、传输模式、控制信号等。 接下来,编写相关的代码来控制OLED显示屏。首先,确保OLED显示屏处于可用状态,并准备好相应的初始设置和功能配置。然后,使用SPI接口的读写函数将数据发送到OLED显示屏或从中读取数据。SPI接口的读写函数可以通过库或者使用直接读写寄存器的方式实现。 在具体的数据传输过程中,需要根据OLED显示屏使用的协议来设置相应的数据格式和控制信号。例如,发送命令和数据之前,需要将DC信号切换到相应的状态;同时,在SPI通信完成之后需要切换CS信号的状态以结束通信。 最后,记得适时进行相关的错误处理和调试。可以根据实际需要来添加适当的延迟等待SPI数据传输完成以及OLED显示屏的响应。 总之,通过配置STM32F103SPI接口以及编写相应的代码,可以实现与OLED显示屏的数据读写。具体的实现方式需要根据OLED显示屏的规格和通信协议来确定。 ### 回答2: 在使用STM32F103芯片进行SPI读写OLED时,我们首先需要了解一些基本概念。 SPI(Serial Peripheral Interface)是一种串行通信协议,用于在微控制器或其他数字芯片之间进行全双工的数据通信。在SPI总线上,有一个主设备(通常是微控制器)和一个或多个从设备(如OLED显示屏)。主设备负责控制总线并发送数据,从设备负责接收数据并做出响应。 要在STM32F103芯片上使用SPI读写OLED,我们需要按照以下步骤进行操作: 1. 硬件连接:首先将STM32F103芯片的SPI引脚与OLED显示屏的SPI引脚连接。通常,STM32F103SPI引脚由标有SCK(时钟线)、MISO(主设备输入,从设备输出)、MOSI(主设备输出,从设备输入)和NSS(片选信号)的引脚组成。 2. 初始化:在代码中,我们需要初始化SPI配置寄存器,设置SPI时钟相位、极性等参数,以及设置NSS引脚的控制方式。还需要初始化OLED显示屏,设置OLED的工作模式和其他参数。 3. 发送数据:通过SPI发送数据到OLED。我们可以使用SPI发送一个字节的数据或一串字节的数据,具体取决于要显示的内容。发送数据的函数通常会等待数据传输完成,然后返回结果。 4. 接收数据(如果需要):如果OLED显示屏返回一些数据,我们可以通过SPI接收数据的功能来读取这些数据。接收数据的函数通常会等待数据传输完成,然后将接收到的数据返回。 通过以上步骤,我们就可以实现STM32F103芯片对OLED显示屏的SPI读写操作。具体的实现方法和代码可以参考STM32F103的相关文档或参考其他开源项目。 ### 回答3: STM32F103是意法半导体生产的一款32位微控制器,具有强大的性能和丰富的外设支持。SPI(Serial Peripheral Interface)是一种串行外设接口协议,用于在微控制器与外部设备之间进行高速数据传输。 要实现STM32F103OLEDSPI读写,可以按照以下步骤操作: 1. 首先,需要将OLED连接到STM32F103SPI端口。OLED通常具有SDA(数据线)、SCL(时钟线)、CS(片选线)、RES(复位线)等引脚,需要将它们连接到STM32F103对应的引脚(如PB14、PB13、PB12、PB11)。 2. 在STM32F103的代码中配置SPI外设。可以使用STM32CubeMX进行外设配置,选择SPI模块,并设置相应的引脚和参数(如波特率、数据位宽等)。 3. 编写代码来初始化SPI外设。在代码中,需要初始化SPI控制寄存器的各个参数,如使能SPI、选择主从模式、设置数据传输顺序等。 4. 编写代码来控制OLED的初始化。在初始化时,可以设置OLED显示参数、清空显示缓存等。 5. 编写代码来实现SPI写入数据到OLED。通过编写SPI发送数据的函数,将要显示的数据发送给OLED。 6. 编写代码来实现SPIOLED读取数据。通过编写SPI接收数据的函数,可以读取OLED的状态信息或其他返回的数据。 7. 在主函数中调用相应的函数,完成SPI读写操作。可以先调用初始化函数,然后通过写入数据和读取数据函数进行SPI读写操作。 综上所述,通过对STM32F103SPI外设配置和编写相应的代码,可以实现与OLED之间的高速数据读写,可以灵活地控制OLED显示

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值