外设驱动库开发笔记34:OLED显示屏驱动

  现在OLED显示屏在嵌入式系统中应用的越来越多。对于一些显示信息不太复杂,以显示信息为主的需求,我们一般会选择OLED显示屏。在这一篇中,我们将讨论OLED显示屏驱动的设计与实现。

1、功能概述

  从使用的情况来说,较为常用的是0.96英寸的OLED128x64的显示屏。这种OLED屏多采用象SSD1306这类驱动芯片,所以我们对OLED屏的操作实际就是对控制芯片的操作。

  对于0.96英寸的OLED128x64的显示屏,其像素点为128x64个,对应在显示RAM中的128x64个位。在显存中,这些区域被划分为8个Page,这些页的划分具体如下图所示:

外设驱动库开发笔记34:OLED显示屏驱动

  在每一页中包括128x8个位对应相应的像素点,对显示像素的操作就是对乡村中对应的位的操作,每页中像素点的排布如下:

外设驱动库开发笔记34:OLED显示屏驱动

  对于操作0.96英寸的OLED128x64显示屏的接口有多种,如6800并行接口、8080并行接口、SPI串行接口以及I2C串行接口等。对于并行接口应用较少,现在应用较多的是SPI和I2C这两种串行总线接口。在SPI接口方式下,有3个控制引脚是需要操作的,分别是复位、数据命令选择和片选信号。而在I2C接口方式下,仅有复位引脚是可控的,但在发送命令或数据时会多一个字节的控制字。

2、驱动设计与实现

  我们已经了解了0.96英寸的OLED128x64显示屏的基本情况,在这里我们来考虑如何实现0.96英寸的OLED128x64显示屏的驱动设计。

2.1、对象定义

  在使用一个对象之前我们需要获得一个对象。同样的我们想要OLED显示屏就需要先定义OLED显示屏的对象。

2.1.1、对象的抽象

  我们要得到OLED显示屏对象,需要先分析其基本特性。一般来说,一个对象至少包含两方面的特性:属性与操作。接下来我们就来从这两个方面思考一下OLED显示屏的对象。

  先来考虑属性,作为属性肯定是用于标识或记录对象特征的东西。我们来考虑0.96英寸的OLED128x64显示屏对象属性。我们考虑SPI和I2C两种接口的情形,所以我们要分辨当前使用的接口形式以确定采取适当的操作方式,所以我们将端口类型设置为其属性以保存当前的操作接口类型。在I2C接口时,每一台I2C从设备都需要有一个设备地址,我们要记录当前从设备的地址,所以将其设置为属性。

  接着我们还需要考虑OLED显示屏对象的操作问题。在SPI接口模式下,我们需要控制复位、数据命令选择以及片选控制引脚,而在I2C接口模式下,我们需要控制复位引脚。这些控制引脚的操作都依赖于具体的硬件平台,所以我们将其作为对象的操作。我们要想OLED发送命令和数据,但不论是何种接口类型这一操作都依赖于具体的软硬件平台,所以我们将其作为对象的操作。为了控制操作时序,我们需要延时操作函数,而延时操作也依赖于具体的软硬件平台,所以我们将其作为对象的操作。

  根据上述我们对OLED显示屏的分析,我们可以定义OLED显示屏的对象类型如下:

/*定义OLED对象类型*/ typedef struct OledObject { uint8_t devAddress; OledPortType port; void (*Write)(struct OledObject *oled,uint8_t *wData,uint16_t wSize); void (*ChipSelcet)(OledCSType en); void (*DCSelcet)(OledDCType dc); void (*ChipReset)(OledRSTType rst); void (*Delayms)(volatile uint32_t nTime); }OledObjectType; 2.1.2、对象初始化

  我们知道,一个对象仅作声明是不能使用的,我们需要先对其进行初始化,所以这里我们来考虑OLED显示屏对象的初始化函数。一般来说,初始化函数需要处理几个方面的问题。一是检查输入参数是否合理;二是为对象的属性赋初值;三是对对象作必要的初始化配置。

  而且0.96英寸的OLED128x64显示屏在实现复位引脚的操作后将实现其初始化配置。据此我们设计OLED显示屏对象的初始化函数如下:

/*OLED显示屏对象初始化*/ void OledInitialization(OledObjectType *oled, //OLED对象 OledPortType port, //通讯端口 uint8_t address, //I2C设备地址 OledWrite write, //写数据函数 OledChipReset rst, //复位信号操作函数指针 OledDCSelcet dc, //DC信号控制函数指针 OledChipSelcet cs, //SPI片选信号函数指针 OledDelayms delayms //毫秒延时函数指针 ) { if((oled==NULL)||(write==NULL)||(rst==NULL) ||(delayms==NULL)) { return; } oled->Write=write; oled->ChipReset=rst; oled->Delayms=delayms; oled->port=port; if(port==OLED_I2C) { if((address==0x3C)||(address==0x3D)) { oled->devAddress=(address<<1); } else if((address==0x78)||(address==0x7A)) { oled->devAddress=address; } else { oled->devAddress=0x00; } if(dc==NULL) { return; } oled->DCSelcet=dc; oled->ChipSelcet=cs; } else { oled->devAddress=0xFF; if(cs==NULL) { oled->ChipSelcet=OledChipSelect; } else { oled->ChipSelcet=cs; } oled->DCSelcet=dc; } oled->ChipReset(OLED_WORK); oled->Delayms(100); oled->ChipReset(OLED_RESET); oled->Delayms(100); oled->ChipReset(OLED_WORK); SendToOled(oled,0xAE,OLEDDC_Command); //关闭显示 SendToOled(oled,0x20,OLEDDC_Command); //Set Memory Addressing Mode SendToOled(oled,0x10,OLEDDC_Command); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid SendToOled(oled,0xB0,OLEDDC_Command); //Set Page Start Address for Page Addressing Mode,0-7 SendToOled(oled,0xA1,OLEDDC_Command); //0xa0,X轴正常显示;0xa1,X轴镜像显示 SendToOled(oled,0xC8,OLEDDC_Command); //0xc0,Y轴正常显示;0xc8,Y轴镜像显示 SendToOled(oled,0x00,OLEDDC_Command); //设置列地址低4位 SendToOled(oled,0x10,OLEDDC_Command); //设置列地址高4位 SendToOled(oled,0x40,OLEDDC_Command); //设置起始线地址 SendToOled(oled,0x81,OLEDDC_Command); //设置对比度值 SendToOled(oled,0x7F,OLEDDC_Command); //------ SendToOled(oled,0xA6,OLEDDC_Command); //0xa6,正常显示模式;0xa7, SendToOled(oled,0xA8,OLEDDC_Command); //--set multiplex ratio(1 to 64) SendToOled(oled,0x3F,OLEDDC_Command); //------ SendToOled(oled,0xA4,OLEDDC_Command); //0xa4,显示跟随RAM的改变而改变;0xa5,显示内容忽略RAM的内容 SendToOled(oled,0xD3,OLEDDC_Command); //设置显示偏移 SendToOled(oled,0x00,OLEDDC_Command); //------ SendToOled(oled,0xD5,OLEDDC_Command); //设置内部显示时钟频率 SendToOled(oled,0xF0,OLEDDC_Command); //------ SendToOled(oled,0xD9,OLEDDC_Command); //--set pre-charge period SendToOled(oled,0x22,OLEDDC_Command); //------ SendToOled(oled,0xDA,OLEDDC_Command); //--set com pins hardware configuration SendToOled(oled,0x12,OLEDDC_Command); //------ SendToOled(oled,0xDB,OLEDDC_Command); //--set vcomh SendToOled(oled,0x20,OLEDDC_Command); //------ SendToOled(oled,0x8D,OLEDDC_Command); //--set DC-DC enable SendToOled(oled,0x14,OLEDDC_Command); //------ SendToOled(oled,0xAF,OLEDDC_Command); //打开显示 OledClearScreen(oled); } 2.2、对象操作

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgyyyy.html