全彩OLED(SSD1351)程序设计与应用(2)显示优化:显存的设计与实现[通俗易懂]

全彩OLED(SSD1351)程序设计与应用(2)显示优化:显存的设计与实现[通俗易懂]本文开发环境:MCU型号:STM32F103ZEIDE环境:MDK5.27显示模块:1.27寸全彩OLED(SSD1351)驱动本文内容:OLED显示简介全彩OLED显存的设计与实现Note:为

全彩OLED(SSD1351)程序设计与应用(2)显示优化:显存的设计与实现[通俗易懂]"

本文开发环境:

  • MCU型号:STM32F103ZE
  • IDE环境: MDK 5.27
  • 显示模块:1.27寸全彩OLED(SSD1351)驱动

本文内容:

  1. OLED 显示简介
  2. 全彩 OLED 显存的设计与实现

Note:为提高传输速度,本文把spi速度由上文工程的9Mpbs调至18Mpbs。这部分与OLED编程无关,故正文不做提及


OLED 系列博客索引 :

  1. 全彩OLED(SSD1351)程序设计与应用(1)驱动的移植
  2. 全彩OLED(SSD1351)程序设计与应用(2)显存优化:显存的设计与实现
  3. 全彩OLED(SSD1351)程序设计与应用(3)字符,字符串以及位图的生成与显示

一、SSD1351 显示原理简介

关于SSD1351显示的原理,可以参考技新科技的教程:SSD1351 设计指南,这里不再赘述,只简单介绍一下,与编程相关的知识点。

1. OLED 绘图原理

在上一小节中,我们已经完成了全屏画一个纯色的函数,其定义如下所示:

void Fill_RAM(unsigned char a, unsigned char b)
{ 
   
    unsigned char i,j;
	Set_Column_Address(0x00,0x7F);                     //设置列的范围 0 ~ 127 (共128列)
	Set_Row_Address(0x00,0x7F);                        //设置行的范围 0 ~ 127 (共127行)

	Set_Write_RAM();                                   //设置写RAM模式,即开始写入像素数据

	for(i=0;i<128;i++)
	{ 
   
		for(j=0;j<128;j++)
		{ 
   
			Write_Data(a);                           //写入颜色高字节
			Write_Data(b);                           //写入颜色低字节
		}
	}
}

在SSD1351中,首先根据我们设置的行列地址,作为起始的坐标,启用RAM后,就开始按顺序一行一行填充颜色,这2两个for()循环语句,正好循环128×128次,保证了每一个像素点都被填充一次,每一次程序都发送了2个字节,这是颜色的数据。SSD1351采用RGB565颜色模式,两个字节16比特,其中每个bit比特含义为:RRRRRGGGGGGBBBBB。可以通过修改Fill_RAM()两个参数的值,来协助自己理解颜色与字节对应的关系。需要特别注意,本文使用的 oled 为1.27寸,其分辨率并非128×128,而是128×96,所以OLED最顶的一行,其行地址是 0x20 ,如果你写一个绘制点的函数,就可以很好的发现这一点——你在(50,50)绘制一个像素点,会发现它距离OLED的边框并不是一样的距离。(注:这是由于初始化造成的,实际上,128×96中,前文OLED_Init() 函数中 **Set_Multiplex_Ratio(0x7F)**参数应该为0x5F,0x7F为128×128驱动的设置,如果你改正此处,坐标值可以正确对应)

二、显示的优化:建立显存数组

在上一节中,我们可以明显的看到颜色刷新的时间,这是由于HAL库函数中 **HAL_SPI_Transmit()**函数代码量较大,而不是直接的控制寄存器,导致需要较长的时间,这个函数调用128x128x2写的时间不低于200ms,导致我们刷新一次屏幕的时候,需要200多毫秒,所以需要HAL_SPI_Transmit()一次性传输128x128x2的数据,而非每次传输1个,传128x128x2次。这就要求我们建立一个大的数组,其大小为 128x128x2 个字节,然后调用库函数,一次性传输。具体操作如下(oled.c 中)所示:

  1. 在 oled.c 中建立一个显存数组:
#define OLED_RAM_SIZE (128*128*2) //定义显存大小
static uint8_t oled_ram[OLED_RAM_SIZE] = { 
   0};      //建立显存
  1. 使用显存方式刷新 oled
/*FILE: oled.c*/
... ...
#include "spi.h" //包含 spi.h 头文件,程序需要使用到spi句柄
void OLED_Refresh(uint8_t *pRAM)
{ 
   
	Set_Column_Address(0x00,0x7F);         			      //设置列地址
	Set_Row_Address(0x00,0x7F);                           //设置行地址
	
	Set_Write_RAM();                                      //开始写RAM
    
    OLED_DC_Clr();	
	uDelay(1);
	OLED_DC_Set();                                         //写数据模式
	uDelay(1);
    HAL_SPI_Transmit(&hspi1,oled_ram,OLED_RAM_SIZE,200);   //发送显存数组
    OLED_DC_Set();       
}
  1. 测试程序
    当我们实现新的刷屏方法以后,就可以编写程序测试效果,(直接修改OLED_Test()函数):
... ...
# include "string.h" //需要使用menset来设置显存函数 
... ...

void OLED_Test(void)
{ 
   
    static uint8_t color = 0x0B;
    memset(oled_ram,color,OLED_RAM_SIZE);   //填充显存颜色
    OLED_Refresh(oled_ram);                 //使用新的方式刷新oled
    color += 0x0A;                          //改变显存颜色
    HAL_Delay(500);
}

当我们运行完该程序以后,就可以发现屏幕的刷新是瞬间完成的,不在看到OLED刷新图片的过程,在以后的工程中,将以填充显存,刷新OLED的方式来显示,避免OLED刷新慢的问题。

  1. oled.c 完整代码:
#include "ssd1351.h"
#include "oled.h"
#include "spi.h"
#include "string.h"

#define OLED_RAM_SIZE (128*128*2)

static uint8_t oled_ram[OLED_RAM_SIZE] = { 
   0};

void OLED_Refresh(uint8_t *pRAM)
{ 
   
	Set_Column_Address(0x00,0x7F);
	Set_Row_Address(0x00,0x7F); 
    
    Set_Write_RAM();
    
    OLED_DC_Clr();	
	uDelay(1);
	OLED_DC_Set();
	uDelay(1);
    HAL_SPI_Transmit(&hspi1,oled_ram,OLED_RAM_SIZE,200);
	OLED_DC_Set();       
}


void Fill_RAM(unsigned char a, unsigned char b)
{ 
   
    unsigned char i,j;
	Set_Column_Address(0x00,0x7F);
	Set_Row_Address(0x00,0x7F);

	Set_Write_RAM();

	for(i=0;i<128;i++)
	{ 
   
		for(j=0;j<128;j++)
		{ 
   
			Write_Data(a);
			Write_Data(b);
		}
	}
}

void OLED_Init(void)
{ 
   
	OLED_RSE_Clr();
	Delay(1);
	OLED_RSE_Set(); 
	Set_Command_Lock(0x12);		    	// Unlock Driver IC (0x12/0x16/0xB0/0xB1)
	Set_Command_Lock(0xB1);		    	// Unlock All Commands (0x12/0x16/0xB0/0xB1)
	Set_Display_On_Off(0x00);	        // Display Off (0x00/0x01)
	Set_Display_Clock(0xF1);	        // Set Clock as 90 Frames/Sec
	Set_Multiplex_Ratio(0x7F);		    // 1/128 Duty (0x0F~0x7F)
	Set_Display_Offset(0x00);           // Shift Mapping RAM Counter (0x00~0x7F)
	Set_Start_Line(0x00);			    // Set Mapping RAM Display Start Line (0x00~0x7F)
	Set_Remap_Format(0x74);			    // Set Horizontal Address Increment
						                // Column Address 0 Mapped to SEG0
                                        // Color Sequence D[15:0]=[RRRRR:GGGGGG:BBBBB]
                                        // Scan from COM127 to COM0
                                        // Enable COM Split Odd Even
                                        // 65,536 Colors Mode (0x74)
                                        // * 262,144 Colors Mode (0xB4)
	Set_GPIO(0x00);				        // Disable GPIO Pins Input
	Set_Function_Selection(0x01);		// Enable Internal VDD Regulator
						                // Select 8-bit Parallel Interface
	Set_VSL(0xA0);				        // Enable External VSL
	Set_Contrast_Color(0xC8,0x80,0xC8);	// Set Contrast of Color A (Red)
						                // Set Contrast of Color B (Green)
						                // Set Contrast of Color C (Blue)
	Set_Master_Current(Brightness);		// Set Scale Factor of Segment Output Current Control
	Set_Gray_Scale_Table();			    // Set Pulse Width for Gray Scale Table
	Set_Phase_Length(0x32);		     	// Set Phase 1 as 5 Clocks & Phase 2 as 3 Clocks
	Set_Precharge_Voltage(0x17);		// Set Pre-Charge Voltage Level as 0.50*VCC
	Set_Display_Enhancement(0xA4);		// Enhance Display Performance
	Set_Precharge_Period(0x01);		    // Set Second Pre-Charge Period as 1 Clock
	Set_VCOMH(0x05);			        // Set Common Pins Deselect Voltage Level as 0.82*VCC
	Set_Display_Mode(0x02);			    // Normal Display Mode (0x00/0x01/0x02/0x03)
	Fill_RAM(0x00,0x00);			    // Clear Screen
	Set_Display_On_Off(0x01);		    // Display On (0x00/0x01)
	
}

void OLED_Test(void)
{ 
   
    static uint8_t color = 0x0B;
    memset(oled_ram,color,OLED_RAM_SIZE);
    OLED_Refresh(oled_ram);
    color += 0x0A;
    HAL_Delay(500);
}

三、说明

由于本次改动只是在上一个工程中修改了oled.c文件,所以只需要复制以上完整代码覆盖上一个工程的 oled.c 文件即可测试,这里不再上传工程,注意上文工程为的SPI速度为9M,本文测试环境为18M。

今天的文章全彩OLED(SSD1351)程序设计与应用(2)显示优化:显存的设计与实现[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88648.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注