STM32进阶教程:使用OLED屏幕模块

STM32进阶-OLED屏幕模块

  • 前言
  • OLED
  • 模块简介
  • 协议
  • SSD1306
  • OLED显示文字的方法
  • 利用软件取模
  • 英文
  • 汉字取模
  • STM32F103与OLED的连接
  • 实验一
  • 实验二
  • 实验三
  • 总结
  • 前言

    实验前言:

    在当今的嵌入式系统开发领域,STM32微控制器因其强大的性能和广泛的应用范围而受到广泛应用。为了进一步扩展其应用范围,我们常常需要与各种外部设备进行交互。其中,OLED屏幕模块作为一种高分辨率、低功耗的显示设备,能够为我们提供丰富的图形和文本信息。
    在本实验中,我们将探讨如何将OLED屏幕模块与STM32微控制器进行连接,并实现基本的信息显示。通过这个实验,我们期望能够更深入地理解OLED屏幕的工作原理,掌握其与STM32的接口技术,为今后的项目开发提供实践经验。
    实验目标:

  • 了解OLED屏幕模块的特性及工作原理。
  • 掌握OLED屏幕模块与STM32微控制器的接口技术。
  • 在OLED屏幕上显示基本的文本和图形信息。
  • 理解并应用I2C通信协议。
    实验器材:
  • STM32F103开发板。
  • OLED屏幕模块SSD1306(128*64分辨率)。
  • 杜邦线若干。
  • 面包板一个。
  • OLED

    模块简介

    OLED(Organic Light Emitting Diode)是一种采用有机物作为发光材料的显示技术。OLED模块由OLED显示屏和控制电路组成,具有高对比度、快速响应、广视角和低功耗等特点,适用于各种嵌入式系统和电子产品中。

    以下是常见的OLED模块的参数表格:

    参数 描述
    分辨率 屏幕的像素数目,如128×64或 256×128等
    显示颜色 支持的颜色数量和色深,如单色、双色或全彩
    尺寸 屏幕的物理尺寸,如0.96寸、1.3寸等
    接口 与控制器通信的接口类型,如SPI、IIC或并行接口等
    供电电压 模块的工作电压范围,如3.3V或5V
    工作温度范围 模块的工作温度范围,如-40°C至85°C
    视角 显示屏的最大可视角度,如水平170°,垂直160°
    亮度调节 支持的亮度调节方式,如软件控制或硬件PWM调光等
    特殊功能 模块可能具有的特殊功能,如触摸屏、按键、指示灯等

    请注意,不同型号和厂商的OLED模块可能具有不同的参数和特性。在选择和使用OLED模块时,需要根据实际需求和项目要求进行选择。
    OLED模块广泛应用于智能手表、可穿戴设备、便携式仪器、嵌入式系统、物联网终端等领域。其高品质的图像显示效果和低功耗的特性,使其成为许多电子产品中理想的显示解决方案。

    协议

    OLED屏幕的通讯协议通常采用SPI通信方式。SPI(Serial Peripheral Interface)是由摩托罗拉公司提出的一种高速全双工的通信总线,它被广泛地应用在ADC、LCD等设备与MCU之间,要求通讯速率较高的场合。
    在OLED屏幕的通讯中,SPI协议通常涉及3条总线以及片选线(SS)。这3条总线分别是SCK(Serial Clock)、MOSI(Master Out Slave In)和MISO(Master In Slave Out)。其中,SCK信号由主机控制产生,MOSI信号由主机发送到从机,MISO信号则由从机发送到主机。片选线(SS)主要用于选择从机,当该线被拉低时,从机被选中并准备接收来自主机的数据。
    SPI通讯的基本过程是这样的:首先,主机通过控制SCK信号的频率和电平来控制通讯速率和数据传输方向。然后,主机通过MOSI线发送数据到从机,同时从机通过MISO线将数据发送回主机。在数据传输过程中,片选线(SS)被用来选择特定的从机设备进行通讯。

    此外,为了确保通讯的稳定性和可靠性,SPI协议还定义了一些通讯时序规则。例如,空闲状态下,SCK信号应该是低电平,而在数据传输过程中,SCK信号的高电平应该在MOSI信号的后面。
    以上信息仅供参考,具体通讯协议和时序规则可能会因不同的OLED屏幕型号和生产商而有所差异。因此,在实际应用中,建议参考相关的技术手册或联系供应商以获取更详细的信息。

    SSD1306

    SSD1306是一种常见的OLED控制驱动芯片,广泛应用于各种OLED模块中。它采用IIC或SPI接口与微控制器通信,具有低功耗、高对比度和快速响应等特点。

    参数 描述
    分辨率 支持的屏幕分辨率,如128×64或 128×32等
    驱动方式 选择的驱动方式,如静态或动态驱动
    接口 与微控制器通信的接口类型,如IIC或SPI接口
    工作电压 芯片的供电电压范围,如3.3V或5V
    工作温度范围 芯片的工作温度范围,如-40°C至85°C
    视角 显示屏的最大可视角度,如水平170°,垂直160°
    像素点亮方式 OLED的像素点亮方式,如逐行扫描或逐列扫描
    驱动电流 OLED显示像素的驱动电流,可根据需要调节
    亮度调节 支持的亮度调节方式,如软件控制或硬件PWM调光等
    特殊功能 芯片可能具有的特殊功能,如内置字库、RAM缓冲区等

    SSD1306芯片具有良好的兼容性和稳定性,被广泛用于各种OLED模块中。它提供了丰富的命令和功能,可实现文本、图形和动画的显示。使用SSD1306芯片,可以轻松控制OLED模块,实现各种实用的显示效果。
    请注意,不同型号和厂商的SSD1306芯片可能具有不同的参数和特性。在选择和使用OLED模块时,需要根据实际需求和项目要求进行选择。


    这个模块默认是使用SPI通讯的,如果要使用I2C通讯,需要把R3电阻取下来,焊接到R1的位置,如上图。

    OLED显示文字的方法

    利用软件取模

    PCtoLCD2002是一款专业的OLED取模软件,它支持多种取模方式,包括逐行、逐列、行列、列行四种取模方式。用户可以根据需要选择字体、大小、文字的长宽,并可独立调整文字的长和宽,生成任意形状的字符。
    该软件还支持中英文数字混合的字符串的字模数据生成,并可以选择字体、大小。同时,每行输出数据个数可调整,且支持自定义取模方式及输出格式。
    值得一提的是,PCtoLCD2002完美版支持生成的字模可以在任何电脑上使用,不会受到操作系统的限制。
    总的来说,PCtoLCD2002完美版是一款功能强大的OLED取模软件,能够满足用户在OLED取模方面的各种需求

    英文

    1. 打开取模软件

    2. 汉字取模
      2.1 点击模式,选择字符模式

      点击选项,进行设置

    设置如下,点阵内的数字手动输入999,然后点击确定。

    1. 以生成8×16字符为例
      3.1字宽,字高选择16,那么对应的英文长宽就是8×16!!!

      在输入栏输入文档开头的全部ASCII码,点击生成字模。

    2. 4将生成的字模复制到oledfont.h的数组中

    汉字取模

    1. 打开取模软件

    2. 汉字取模
      2.1 点击模式,选择字符模式

      点击选项,进行设置
      设置如下,点阵内的数字手动输入999,然后点击确定。

    3. 以生成16×16的汉字为例
      3.1字宽,字高选择16

      在输入栏输入需要取模的汉字(只能是汉字),然后点击生成字模。

    4. 将生成的字模复制到oledfont.h的数组中

    STM32F103与OLED的连接

    代码:

    OLED.c 内容过多,此处只讲OLED.h部分,具体函数请读者自行编写或查阅

    #ifndef __OLED_H
    #define __OLED_H
    
    void OLED_Init(void);
    void OLED_Clear(void);
    void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char);
    void OLED_ShowString(uint8_t Line, uint8_t Column, char *String);
    void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
    void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length);
    void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
    void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
    
    #endif
    

    这段代码是一个简单的OLED库的头文件,定义了一些函数来控制OLED显示屏的初始化、清屏以及显示字符、字符串、数字和二进制数等功能。
    函数解释:

  • OLED_Init():初始化OLED显示屏。
  • OLED_Clear():清除OLED显示屏上的内容。
  • OLED_ShowChar(uint8_t Line, uint8_t Column, char Char):在指定的行和列位置显示一个字符。
  • OLED_ShowString(uint8_t Line, uint8_t Column, char *String):在指定的行和列位置显示一个字符串。
  • OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length):在指定的行和列位置显示一个无符号整数。
  • OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length):在指定的行和列位置显示一个有符号整数。
  • OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length):在指定的行和列位置显示一个十六进制数。
  • OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length):在指定的行和列位置显示一个二进制数。
  • 这些函数可以通过调用库文件中的相关函数来实现OLED显示屏的控制和数据显示。用户可以根据需要调用这些函数来显示不同的内容。
    示例

    void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
    {
    	uint8_t i;
    	for (i = 0; i < Length; i++)							
    	{
    		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
    	}
    }
    

    这段代码是OLED_ShowNum()函数的实现,用于在OLED显示屏上显示一个无符号整数。
    函数解释:

  • OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length):函数接受四个参数,分别是要显示的数字所在的行和列位置、要显示的数字以及数字的长度。
  • for (i = 0; i < Length; i++):使用循环来逐个显示数字的每一位。
  • OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0'):调用OLED_ShowChar()函数来显示每一位数字。具体的显示位置由LineColumn + i确定。通过对Number进行数学运算,可以得到每一位数字的值,并将其转换为对应的字符形式。
  • 该函数通过循环将数字分解为每一位,并调用OLED_ShowChar()函数来在OLED显示屏上逐个显示每一位数字。用户可以通过调用该函数,传入相应的参数来实现在OLED显示屏上显示无符号整数的功能。

    实验一

    显示自己的学号和姓名;
    利用汉字取模软件:

    生成的编码放到oled_front.h中:

    main函数:

    #include "stm32f10x.h"                 
    #include "Delay.h"
    #include "OLED.h"
    #include "Delay.h"
    #include "LED.h"
    #include "usart.h"
    
    extern unsigned int rec_data[4];
    
    int main(void)
    {
    	OLED_Init();
    	
    	OLED_ShowHZ(1,1,12);
    	OLED_ShowHZ(1,3,14);
    	OLED_ShowHZ(1,5,16);
    	OLED_ShowString(2,1,"632107030112");
    	while (1)
    	{
    		
    	}
    
    }
    
    

    实验效果:

    实验二

    显示AHT20的温度和湿度:

    #include "stm32f10x.h"                 
    #include "Delay.h"
    #include "OLED.h"
    #include "Delay.h"
    #include "LightSensor.h"
    #include "LED.h"
    #include "dht20.h"
    #include "usart.h"
    
    extern unsigned int rec_data[4];
    
    int main(void)
    {
    	OLED_Init();
    	uart_init(9600);
    	LightSensor_Init();
    	LED_Init();
    	OLED_ShowHZ(2,5,0); //ÎÂ
    	OLED_ShowHZ(2,7,2); //¶È
    	OLED_ShowHZ(2,9,4);	//:
    	OLED_ShowHZ(2,12,6);//¡æ
    
    	OLED_ShowHZ(4,5,8); //ʪ
    	OLED_ShowHZ(4,7,10); //¶È
    	OLED_ShowHZ(4,9,4); //:
    	OLED_ShowChar(4,12,'%');//%
    	
    	while (1)
    	{
    		Delay_s(1);
    		DHT20_REC_Data(); //½ÓÊÕdht20Êý¾Ý
    	    OLED_ShowNum(2,10,rec_data[2],2);
    		OLED_ShowNum(4,10,rec_data[0],2);
    		if (LightSensor_Get() == 1)
    		{
    				LED2_ON();
    		}
    		else
    		{
    				LED2_OFF();
    		}
    	}
    
    }
    
    

    实验效果:

    实验三

    上下或左右的滑动显示长字符:
    代码:

    	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); //终止页 2
    	OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节
    	OLED_WR_Byte(0xFF,OLED_CMD); //虚拟字节
    	TEST_MainPage();
    	OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动
    

    这段代码是用于控制OLED屏幕进行滚动显示的操作。下面是对代码的解释:

    OLED_WR_Byte(0x2E,OLED_CMD); //关闭滚动
    

    这行代码发送命令给OLED屏幕,将滚动功能关闭。

    OLED_WR_Byte(0x27,OLED_CMD); //水平向左或者右滚动 26/27
    

    这行代码发送命令给OLED屏幕,选择水平滚动的方向,可以选择向左滚动或者向右滚动。具体选择通过参数0x27或者0x26来确定。

    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); //终止页 2
    OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节
    OLED_WR_Byte(0xFF,OLED_CMD); //虚拟字节
    

    这些代码依次发送命令给OLED屏幕,设置滚动的参数。包括设置起始页和终止页、滚动时间间隔等参数。其中0x00和0xFF是虚拟字节,可能是为了补齐命令的格式。

    TEST_MainPage();
    

    这行代码调用了TEST_MainPage函数,可能用于设置OLED屏幕要滚动显示的内容。

    OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动
    

    这行代码发送命令给OLED屏幕,将滚动功能开启。
    以上就是对给定代码的解释,它们用于控制OLED屏幕进行滚动显示的操作。具体的功能和效果可能需要参考OLED屏幕的文档或者相关代码来确定。

    实验效果

    突发奇想:

    #include "stm32f10x.h"                 
    #include "Delay.h"
    #include "OLED.h"
    #include "Delay.h"
    #include "LED.h"
    #include "usart.h"
    
    
    
    int main(void)
    {
    	OLED_Init();
    
    	while (1)
    	{
    		for(int i=1;i<=8;i++)
    		{
    				OLED_ShowHZ(2,i,18);
    	      OLED_ShowHZ(2,i+2,20);
    	      OLED_ShowHZ(2,i+4,22);
    	      OLED_ShowHZ(2,i+6,24);
    	      OLED_ShowString(3,i,"cqjtu!");
    			  Delay_ms(50);
    			  OLED_Clear();
    		}
    		Delay_ms(500);
    		OLED_Clear();
    	}
    
    }
    
    
    

    好像这样直接改变字符显示的位置也可以刷屏

    对比
    在OLED刷屏的方法上,通常有两种主要的策略:

    直接发送命令和数据: 在这种方法中,你直接发送特定的OLED命令和数据来控制OLED显示屏。例如,你可能发送一个命令来显示一个特定的字符,或者一个命令来滚动文本。这种方法的优点是它通常比较简单和直接。然而,它的缺点是它可能需要更多的代码和处理器时间,因为它需要在主循环中持续地发送命令和数据。
    使用库或驱动程序: 在这种方法中,你使用一个预先编写好的库或驱动程序来控制OLED显示屏。这些库或驱动程序通常包含了许多用于控制显示屏的函数和命令,可以让你以更高效和更简洁的方式控制显示屏。这种方法的优点是它可以减少代码的复杂性和处理器时间的使用。然而,它的缺点是你可能需要适应特定的库或驱动程序,而且可能需要更多的理解和配置工作。
    在你的代码中,你使用了第一种方法,即直接发送命令和数据来控制OLED显示屏。例如,你发送了OLED_WR_Byte(0x2E,OLED_CMD); //关闭滚动 和 OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动等命令来控制滚动功能。同时,你也直接发送了OLED_ShowHZ(2,i,18);等命令来显示特定的字符。

    总结

    本次实验中,我们成功实现了对OLED屏幕模块的控制和数据显示功能。首先,我们理解了OLED屏幕的工作原理和汉字点阵编码原理,了解了控制OLED屏幕的SPI或IIC接口的基本配置和通信方式。然后,我们使用STM32F103单片机通过SPI或IIC接口与OLED屏幕进行通信,并通过编写代码实现了以下功能:

  • 显示自己的学号和姓名:通过将学号和姓名的字符串数据发送到OLED屏幕,实现了学号和姓名的显示功能。
  • 显示AHT20的温度和湿度:将AHT20传感器读取到的温度和湿度数据转换为字符串,并将其发送到OLED屏幕,实现了温度和湿度的显示功能。
  • 上下或左右滑动显示长字符:通过在OLED屏幕上不断滚动显示长字符的方法,实现了滑动显示长字符的效果。可以自定义长字符内容。
  • 通过本次实验,我深入理解了OLED屏幕的工作原理和控制方法,掌握了STM32单片机与OLED屏幕之间的通信和数据显示。这将为我在物联网等领域中使用OLED屏幕提供了基础和启示。同时,通过实践,我也提高了对STM32F103单片机的编程能力和对硬件与软件的综合应用能力。

    作者:Alone–阮泽宇

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32进阶教程:使用OLED屏幕模块

    发表评论