• STM32F4X OLED使用


    OLED简介

    OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。
    OLED跟LCD不同,LCD需要背光才能点亮,而OLED不需要背光,因为它是自发光。因为技术的原因,目前OLED不能做得很大,目前常见的OLED尺寸有0.96、1.3、1.54和2.42寸。本节实验将会使用2.42寸、分辨率为128*64的OLED做实验。

    OLED使用

    OLED驱动芯片

    通常OLED内部都会一块OLED的驱动芯片,驱动芯片的作用是接收用户发送的数据,将数据进行管理,最后将数据显示到OLED上。常见的OLED驱动芯片有SSD1306、SSD1309等,操作OLED实际就是操作OLED的驱动芯片。本次实验用的驱动芯片是SSD1309。

    SSD1309引脚

    引脚作用
    CS片选信号,低电平有效
    RES复位信号
    D/C数据、命令引脚。低电平为写命令、高电平为写数据
    R/WMCU接口的读写控制输入引脚
    EMCU接口输入
    D7~D0并行传输接口
    BS2~BS0OLED通信接口选择

    SSD1309通信协议

    SSD1309支持并行通信和串行通信,具体的通信方法选择是通过BS2~BS0引脚进行选择。

    BS[2:0]接口
    0004线SPI
    0013线SPI
    010I2C
    1108-bit 8080接口
    1008-bit 6800接口

    4线SPI模式

    将BS[2:0]设置为000即可进入4线SPI模式,在4线SPI模式下,需要7根通信引脚

    引脚作用
    RES复位信号
    D/C写数据、写命令
    CS片选
    D0用作SCL
    D1用作SDA
    VCC电源
    GND地线

    在这里插入图片描述

    1. 先将CS信号拉低,代表选中OLED,开始通信
    2. 根据用户发送的数据还是命令,选择D/C信号的电平,低电平为发送命令,高电平为发送数据
    3. 将需要发送的数据(8bit)按照高位在前的方式,在时钟信号的上升沿发送给OLED
    4. 数据发送完之后,再将CS拉高。

    3线SPI模式

    将BS[2:0]设置为001即可进入3线SPI模式,在4线SPI模式下,需要6根通信引脚

    引脚作用
    RES复位信号
    CS片选
    D0用作SCL
    D1用作SDA
    VCC电源
    GND地线

    在这里插入图片描述
    3线SPI模式跟4线SPI模式非常相似,主要区别是3线SPI模式下没有D/C信号线,D/C信号是以数据的形式发送出去。

    1. 先将CS信号拉低,代表选中OLED,开始通信
    2. 在需要发送的数据前添加一个D/C选择位,0为发送命令,1为发送数据
    3. 将需要发送的数据(9bit)按照高位在前的方式,在时钟信号的上升沿发送给OLED
    4. 数据发送完之后,再将CS拉高。

    I2C模式

    将BS[2:0]设置为010即可进入I2C模式,在I2C模式下,需要5根通信引脚

    引脚作用
    RES复位信号
    SCL时钟线
    SDA数据线
    VCC电源
    GND地线
    OLED地址确认

    凡是涉及到I2C通信,从机设备都要确定好地址,SSD1309的地址设置如下

    A6A5A4A3A2A1A0R/W
    011110SA01/0

    SA0为地址选择信号,由D/C信号线决定,也就是说一个I2C总线上可以接2个OLED设备。

    在这里插入图片描述

    1. 主机发送起始信号,告诉从机开始通信
    2. 主机等待从机ACK信号
    3. 主机发送控制字节
    4. 主机等待从机ACK信号
    5. 主机发送数据
    6. 主机等待从机ACK信号
    7. 主机发送停止信号,结束通信。

    使用I2C通信需要注意控制字节的配置字。控制字节的高6位是D/C信号,bit为0代表发送命令,bit为1代表发送数据。
    控制字节的高7位是设置是否需要连续发送显示数据,其目的是让OLED快速刷屏。我们通过上图的通信协议知道,当我们每次需要发送一个字节时,都需要开启一个完整的I2C通信,如果需要大量数据刷屏时就很浪费时间,当Co为0且D/C为1时,则开启连续发送数据模式,只需启动一个I2C通信,就可以连续发送数据,直到停止。

    8080接口

    将BS[2:0]设置为110即可进入8080模式,在8080模式下,需要15根通信引脚

    引脚作用
    RES复位信号
    CS片选
    D/C写命令、写数据信号
    RD读数据信号,低电平有效
    WR写数据,低电平有效
    D7~D0并行数据口
    VCC电源
    GND地线
    OLED 8080写模式

    在这里插入图片描述

    • 将CS信号拉低,开始通信
    • 将WR信号拉低,同时将RD信号拉高,代表写模式
    • 根据是写命令还是写数据选择D/C电平信号
    • 将数据通过D7~D0引脚发送到OLED
    • 将CS信号拉高,WR信号拉高,结束通信
    OLED 8080读模式

    在这里插入图片描述

    • 将CS信号拉低,开始通信
    • 将RD信号拉低,同时将WR信号拉高,代表读模式
    • 根据是写命令还是写数据选择D/C电平信号
    • 读出D7~D0上的数据
    • 将CS信号拉高,RD信号拉高,结束通信

    6800接口

    将BS[2:0]设置为100即可进入8080模式,在6800模式下,需要15根通信引脚

    引脚作用
    RES复位信号
    CS片选
    D/C写命令、写数据信号
    RW读写信号
    D7~D0并行数据口
    E使能信号
    VCC电源
    GND地线

    在这里插入图片描述

    SSD1309显示原理

    SSD1309显存大小

    OLED本身是没有存储显示数据的功能,这个功能是由SSD1309提供,SSD1309内部提供了一块显存区域,其分辨率为128 * 64,这个分辨率也就是OLED的分辨率。意思是这块OLED最多可以显示128 * 64位的数据,也就是1024个字节,长度最大为128,宽度最大为64。
    在这里插入图片描述

    SSD1309显存分布

    SSD1309内部的显存大致如下分布。
    在这里插入图片描述
    SSD1309内部的显存可以划分成128 * 64个格子,每个格子代表一个bit。SSD1309又将这些格子进一步划分,按照8列为一组,分成了8页,每页大小为128 * 8个格子,也就是128字节为一页。
    在这里插入图片描述

    SSD1039数据显示

    我们拿其中一页作为例子,来说一下在SSD1309内部数据是怎样存放的。我们需要知道的是在SSD1309内部,所有的数据都是按照列来存放,假设我们在PAGE0的(0,0)这个位置写入一个数据0xAC,那么其存储格式如下。最低位在前,高位在后。
    在这里插入图片描述

    MCU操作SSD1309显存方法

    针对SSD1309的显存存储结构,MCU每次修改数据的时候都需要将SSD1309的显存数据读出来,确保旧的数据跟新的数据没有冲突,但是这就有一个问题,每次修改数据的数据都需要读显存数据,这样就很浪费时间。所以在实际应用中,一般都会在MCU中定义一个128*64bit大小的二维数组,这个数组可以看做是SSD1309的外部显存,每次需要更新数据时,都会更新这个外部显存,最后再通过命令把整个显存数据刷新到SSD1309内部。

    OLED取模

    由于SSD1309内部是没有字库的,所以我们需要自己制作字库文件,这样OLED才能显示图片、字符等。字库的制作软件PCtoLCD2002,软件大家可以自行到网上进行下载。

    字符取模

    我们需要制作常用的ASCII码字符,需要制作的字符如下,第一个ASCII码为空格

     !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
    
    • 1
    • 设置软件为字符取模模式

    在这里插入图片描述

    • 点击选项,进入设置模式,按照以下方法进行取模设置

    在这里插入图片描述

    • 以生成8x16字符为例

    在这里插入图片描述
    在这里插入图片描述
    在生成字符前先选择字符的高度和宽度,然后将需要生成的字符复制到输入框内,点击生成字模,最后点击保存字模,生成后的字模就会保存到文件中。

    图片取模

    例程位图图片下载

    • 设置图片大小
      首先点击上面的网址,下载图片。下载完成后打开windows的画图软件,修改图片分辨率为128 * 64。
      在这里插入图片描述
      修改完成后将图片另存为BMP格式的图片。
    • 设置软件为图片取模模式
      在这里插入图片描述
    • 设置取模模式
      在这里插入图片描述
    • 生成图片字模
      在这里插入图片描述
      将制作好的BMP图片加载到软件中,点击生成字模,然后点击保存字模。

    STM32F4X OLED例程

    本节例程中用到的OLED是128 * 64分辨率的OLED,通信协议是4线SPI协议。
    在这里插入图片描述
    在这里插入图片描述

    OLED关键函数讲解

    数据传输函数

    
    void oled_write_byte(unsigned char byte,unsigned char type)
    {
    	unsigned char i;
    	GPIO_ResetBits(OLED_CS_PIN_PORT,OLED_CS_PIN); // CS 拉低
    	
    	if(OLED_WRITE_CMD == type)   
    		GPIO_ResetBits(OLED_DC_PIN_PORT,OLED_DC_PIN); // 写命令 拉低DC
    	else
    		GPIO_SetBits(OLED_DC_PIN_PORT,OLED_DC_PIN); // 写数据 拉高DC
    	
    	
    	for(i = 0;i < 8;i++)  // 传输数据
    	{
    		GPIO_ResetBits(OLED_SCL_PIN_PORT,OLED_SCL_PIN); // 拉低SCL
    		
    		if(byte & 0x80)
    			GPIO_SetBits(OLED_SDA_PIN_PORT,OLED_SDA_PIN);
    		else
    			GPIO_ResetBits(OLED_SDA_PIN_PORT,OLED_SDA_PIN);
    		
    		GPIO_SetBits(OLED_SCL_PIN_PORT,OLED_SCL_PIN); // 拉高SCL
    		byte <<= 1; // 数据左移一位
    	}
    	GPIO_SetBits(OLED_CS_PIN_PORT,OLED_CS_PIN); // 拉高CS
    	GPIO_SetBits(OLED_DC_PIN_PORT,OLED_DC_PIN); // 拉高DC
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在开始传输数据前,要先把CS信号拉低,代表选中OLED,然后根据是写命令还是写数据,改变D/C信号电平,在SCL的上升沿的时候把数据按照高位在前,低位在后依次发送给OLED,最后拉高CS和D/C信号。
    程序的实现都是按照数据手册的时序要求进行设计。
    在这里插入图片描述

    画点函数

    void oled_drawpoint(unsigned char x,unsigned char y,unsigned char t)
    {
        u8 i,m,n;
        i=y/8; // 判断是第几页
        m=y%8; // 判断是第几位
        n=1<<m;
    
        if(t){OLED_GRAM[x][i]|=n;} // 如果是1就直接写数据
        else
        { // 如果是0,就清0
            OLED_GRAM[x][i]=~OLED_GRAM[x][i];
            OLED_GRAM[x][i]|=n;
            OLED_GRAM[x][i]=~OLED_GRAM[x][i];
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在往GRAM写数据前,先判断该点位于GRAM的页数,然后再判断该点是第几个bit,最后再根据是否需要点亮该bit进行写1或者清0操作。

    写GRAM

    static  unsigned char OLED_GRAM[128][8];
    //更新显存到OLED
    void oled_refresh(void)
    {
        u8 i,n;
        for(i=0;i<8;i++)
        {
           oled_write_byte(0xb0+i,OLED_WRITE_CMD); //设置页
           oled_write_byte(0x00,OLED_WRITE_CMD);   //设置低列起始地址
           oled_write_byte(0x10,OLED_WRITE_CMD);   //设置高列起始地址
           for(n=0;n<128;n++)
             oled_write_byte(OLED_GRAM[n][i],OLED_WRITE_DATA);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    程序会先定义一个128*8的二维数据,数据类型为unsigned char类型,也就是1024个字节,用户更新完数据后,再将这个GRAM刷新到SSD1309内部的GRAM中,从而实现了更新OLED的目的。

    完整例程

    由于例程过大,请在百度网盘下载
    链接:https://pan.baidu.com/s/1ZjxPKjeIG1PyOVn7OHIjeQ
    提取码:z59g

    在这里插入图片描述

    因本人水平有限,错误和疏漏之处在所难免,欢迎指正。

  • 相关阅读:
    数据挖掘与机器学习
    yolov5s V6.1版本训练PASCAL VOC2012数据集&yolov5官网教程Train Custom Data
    05.[图解TCPIP(第5版) 文档简单整理
    [问题已处理]-在win10上安装prometheus监控
    【算法刷题日记之本手篇】计算日期到天数转换与幸运的袋子
    2、配置git环境与项目创建
    mysql8.0英文OCP考试第111-120题
    stm32f103c8t6最小系统引脚及功能原理图
    硬实力+软实力!2023功能测试进阶之路!
    ROI的投入产出比是什么?
  • 原文地址:https://blog.csdn.net/hwx1546/article/details/133808891