首页 > 其他分享 >OLED屏幕

OLED屏幕

时间:2025-01-03 16:30:18浏览次数:3  
标签:0x08 u8 0x20 0x00 Oled OLED 0x80 屏幕

OLED简介

OLED(Organic Light-Emitting Diode,有机发光二极管)显示屏由许多微小的发光二极管构成,每个发光二极管就对应着屏幕上的一个像素,通过控制二极管的亮灭就能在屏幕上显示图像或文字。

按照驱动方式划分,OLED显示屏分可分为两类,分别是PMOLED(Passive Matrix,被动矩阵)和AMOLED(Active Matrix,主动矩阵)。

  • PMOLED

PMOLED的驱动方式和前文的LED点阵类似,每次只能点亮一行或者一列,需要快速的逐行或者逐列扫描来显示内容。

  • AMOLED

AMOLED屏幕上的每个像素点都有一个单独的控制电路,可以独立进行控制。

本次介绍的是一块PMOLED(Passive Matrix,被动矩阵)屏,其分辨率为128x64。

驱动芯片

市面上的多数OLED显示屏都会带有驱动芯片,驱动芯片的核心作用是控制每个像素点的亮灭以显示图像或文字,此外它还会提供数据接口(例如I2C),用于接收屏幕上要显示的数据。驱动芯片的存在使得我们可以通过简单的接口控制OLED显示屏,大大简化了开发和控制流程。

本次介绍的这块OLED屏的驱动芯片为SSD1315

基本工作原理

SSD1315原理图

  • MCU InterFace
    通信接口,MCU通过该接口向SSD1315发送显示数据或者控制命令(控制屏幕显示效果,例如对比度、亮度等)。该接口支持多种通信协议,其中就包括IC。
  • Command Decoder
    命令解码器,负责解析和执行主机发送的控制命令
  • Graphic Display Data RAM
    图形显示数据RAM,用于存储显示数据,其容量为128x64(bit)。每个bit对应屏幕上的1个像素。
  • Common/Segment Driver
    用于产生实际驱动OLED显示屏的信号。其中Common Driver用于产生行扫描信号共有64个输出引脚。Segment Driver用于产生每行要显示的内容信号,共有128个输出引脚。

IIC接口、写时序

SSD1315的MCU Interface支持多种通信协议,这里OLED显示模块只暴露出了IIC接口

OLED显示屏的作用是显示数据,是一个输出设备,我们只需关注如何向SSD1315写入数据即可。下面是写数据的时序图
写时序图

  • SA0
    SSD1315的地址,高6位是固定的011110,最后1位SA0可由用户自定义。参考0LED模块手册,可得最后1位的默认值为0
  • R/W#
    R/W#(读写标识)应为0,故地址+读写标识应为01111000(0x78)
  • Data byte
    数据字节,其内容可能是Data(显示数据),也可能是Command(控制命令)。
  • Control byte
    控制字节,在Data byte之前发送,用于声明后续Data byte内容的类型和格式,该字节只有高2位有效,其余6位均为0
  • D/C#(Data/Command)
    用于声明后续的Data byte是Data还是Command,1表示Data,0表示Command。
  • Co(Continuation Bit)
    用于声明后续内容是否连续,0表示连续,此时后边可以连续发送多个Data bvte:1表示不连续,此时后边只能发送一个Data byte。需要注意的是,当Co设置0时,本次通信中后续所有的字节都会被视作Databyte

内存组织结构

在这里插入图片描述
在这里插入图片描述

​​​​​​​内存寻址

定位一个byte,至少需要明确两点,分别是第几页(Page Address,页地址)和第几列(Column Address,列地址)。

GDDRAM内部设有两个指针

  • Page Address Pointer,指向当前要写入的
  • Column Address Pointer,指向当前要写入的

为方便连续写入多个字节,每当成功写入一个字节后,Page Address Pointer或者Column Address Pointer会自动递增,指向下一个要写入的位置。

设置寻址方式的命令
在这里插入图片描述

页寻址

这种寻址方式下,用户需要先向SSD1315发送控制命令设置页地址(例如Page1)和列地址(例如COL3),此时Page Address Pointer和Column Address Pointer就会指向对应的位置。之后便可开始连续发送数据,每成功写入一个字节,Column Address Pointer都会自动+1,而Page Address Pointer始终不变,如果写到当前页末尾,Column Address Pointer会回到当前页的第1列。

设置页地址的命令如下。
在这里插入图片描述
设置列地址的命令如下。
在这里插入图片描述

水平寻址

这种寻址方式下,用户需要先向SSD1315发送控制命令,设置一个写入区域,具体来讲就是分别指定页的起始地址和结束地址(例如Page1Page5)以及列的起始地址和结束地址(例如COL2COL125)。此时Page Address Pointer和Column Address Pointer会指向该区域的左上角。之后便可开始连续发送数据,每成功写入一个字节,Column Address Pointer会自动+1,当到达目标区域的右侧边界时,Page Address Pointer便会自动+1。当写到目标区域的右下角时,两个指针会再次回到左上角。

设置页地址范围的命令如下。
在这里插入图片描述

设置列地址范围的命令如下。
在这里插入图片描述

垂直寻址

这种寻址方式下,用户需要先向SSD1315发送控制命令,设置一个写入区域,具体来讲就是分别指定页的起始地址和结束地址(例如Page1Page5)以及列的起始地址和结束地址(例如COL2COL125)。此时Page Address Pointer和Column Address Pointer会指向该区域的左上角。之后便可开始连续发送数据,每成功写入一个字节,Page Address Pointer会自动+1,当到达目标区域的底部边界时,Column Address Pointer便会自动+1。当写到目标区域的右下角时,两个指针会再次回到左上角。

​​​​​​​内存bit与屏幕像素映射关系

GDDRAM中的每个bit都对应着屏幕上的一个像素,但具体哪个bit对应着哪个像素,目前仍是不明确的,最理想的方式当然是每个bit和每个像素的位置完全对应,但默认情况下并非如此。

bit和像素之间的对应关系受两个环节的影响,第一个环节是GDDRAM和SSD1315输出引脚(64个COM和128个SEG)的对应关系,第二个环节是SSD1315的输出引脚和OLED屏幕的连线方式。下面逐一分析。

GDDRAM和SSD1315输出引脚对应关系
在这里插入图片描述

SSD1315输出引脚和OLED屏幕对应关系
在这里插入图片描述

根据前文的描述,若要保证GDDRAM中的bit与OLED屏幕中的像素位置完全对应,那么GDDRAM和SSD1315输出引脚的对应关系,需要进行重映射。

设置Segment重映射的命令如下。
在这里插入图片描述
设置Common重映射的命令如下。
在这里插入图片描述

代码实现

Int_Oled.h

#ifndef __INT_OLED_H__
#define __INT_OLED_H__
#include "Com_Util.h"
/**
 * @brief Oled初始化
 *
 */
void Int_Oled_Init();

void Int_Oled_WriteData(u8 bytes[], u8 length);
void Int_Oled_WriteCmd(u8 bytes[], u8 length);

/**
 * @brief 清屏
 *
 */
void Int_Oled_Clear();

/**
 * @brief 在指定位置(x,y)显示字符串
 *
 * @param x 横坐标
 * @param y 纵坐标
 * @param str 待展示字符串
 */
void Int_Oled_ShowStr(u8 x, u8 y, u8* str);

/**
 * @brief 在指定位置(x,y)显示数字
 *
 * @param x 横坐标
 * @param y 纵坐标
 * @param num 待展示数字
 */
void Int_Oled_ShowNum(u8 x, u8 y, long int num);

#endif /* __INT_OLED_H__ */

Int_Oled.c

#include "Int_Oled.h"
#include "Dri_IIC.h"
#define OLED_ADDR 0x78
#define DATA_MODE 0x40
#define CMD_MODE  0x00

code const u8 Int_Oled_Font[][16] =
    {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  0

        0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //! 1

        0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //" 2

        0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00,
        0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // # 3

        0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00,
        0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$ 4

        0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00,
        0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //% 5

        0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00,
        0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //& 6

        0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //' 7

        0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00,
        0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //( 8

        0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00,
        0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //) 9

        0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00,
        0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //* 10

        0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00,
        0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+ 11

        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //, 12

        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //- 13

        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //. 14

        0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04,
        0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, /// 15

        0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00,
        0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16

        0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17

        0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00,
        0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18

        0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00,
        0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19

        0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00,
        0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20

        0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00,
        0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21

        0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00,
        0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22

        0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00,
        0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23

        0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00,
        0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24

        0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00,
        0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25

        0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //: 26

        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //; 27

        0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00,
        0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //< 28

        0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //= 29

        0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00,
        0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //> 30

        0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00,
        0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //? 31

        0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00,
        0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@ 32

        0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00,
        0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33

        0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00,
        0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34

        0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00,
        0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35

        0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00,
        0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36

        0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00,
        0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37

        0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00,
        0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38

        0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00,
        0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39

        0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08,
        0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40

        0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00,
        0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41

        0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00,
        0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42

        0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00,
        0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43

        0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44

        0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00,
        0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45

        0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08,
        0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46

        0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00,
        0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47

        0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00,
        0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48

        0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00,
        0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49

        0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00,
        0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50

        0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00,
        0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51

        0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00,
        0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52

        0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08,
        0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53

        0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08,
        0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54

        0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00,
        0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55

        0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08,
        0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56

        0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00,
        0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57

        0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00,
        0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58

        0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00,
        0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[ 59

        0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\ 60

        0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00,
        0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //] 61

        0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^ 62

        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_ 63

        0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //` 64

        0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
        0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65

        0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00,
        0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66

        0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00,
        0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67

        0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00,
        0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68

        0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
        0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69

        0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18,
        0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70

        0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
        0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71

        0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00,
        0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72

        0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73

        0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00,
        0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74

        0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00,
        0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75

        0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76

        0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
        0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77

        0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00,
        0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78

        0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
        0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79

        0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00,
        0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80

        0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00,
        0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81

        0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00,
        0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82

        0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
        0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83

        0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84

        0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00,
        0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85

        0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80,
        0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86

        0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80,
        0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87

        0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00,
        0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88

        0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80,
        0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89

        0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
        0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90

        0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{ 91

        0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //| 92

        0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00,
        0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //} 93

        0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~ 94
};



/**
 * @brief 写显示数据
 *
 * @param bytes 字节数组
 * @param length 数组长度
 */
void Int_Oled_WriteData(u8 bytes[], u8 length)
{
    u8 i;
    // 发送起始信号
    Dri_IIC_Start();
    // 发送设备地址
    Dri_IIC_SendByte(OLED_ADDR);
    Dri_IIC_ReceiveAck();
    // 发送控制字节
    Dri_IIC_SendByte(DATA_MODE);
    Dri_IIC_ReceiveAck();
    // 发送数据
    for (i = 0; i < length; i++) {
        Dri_IIC_SendByte(bytes[i]);
        Dri_IIC_ReceiveAck();
    }
    Dri_IIC_Stop();
}

/**
 * @brief 写控制命令
 *
 * @param bytes 字节数组
 * @param length 数组长度
 */
void Int_Oled_WriteCmd(u8 bytes[], u8 length)
{
    u8 i;
    // 发送起始信号
    Dri_IIC_Start();
    // 发送设备地址
    Dri_IIC_SendByte(OLED_ADDR);
    Dri_IIC_ReceiveAck();
    // 发送控制字节
    Dri_IIC_SendByte(CMD_MODE);
    Dri_IIC_ReceiveAck();
    // 发送数据
    for (i = 0; i < length; i++) {
        Dri_IIC_SendByte(bytes[i]);
        Dri_IIC_ReceiveAck();
    }
    Dri_IIC_Stop();
}

void Int_Oled_Init()
{
    u8 bytes[6];
    // 关闭屏幕
    bytes[0] = 0xAE;
    // Segment重映射
    bytes[1] = 0xA1;
    // Common重映射
    bytes[2] = 0xC8;
    // 启动内置电荷泵(用于升压)
    bytes[3] = 0x8D;
    bytes[4] = 0x14;

    // 开启屏幕
    bytes[5] = 0xAF;
    Int_Oled_WriteCmd(bytes, 6);
}

void Int_Oled_Clear() {
    u8 cmd_bytes[2]={0x20,0x00};
    u8 data_bytes[8] = {0};
    u8 i;
    Int_Oled_WriteCmd(cmd_bytes, 2);
    for ( i = 0; i < 128; i++)
    {
        Int_Oled_WriteData(data_bytes, 8);
    }
}

/**
 * @brief 设置页地址和列地址
 *
 * @param page 页地址
 * @param column 列地址
 */
void Int_Oled_SetPointer(u8 page, u8 column)
{
    u8 bytes[3];
    bytes[0] = 0xB0 | (page & 0x07);
    bytes[1] = 0x00 | (column & 0x0F);
    bytes[2] = 0x10 | ((column >> 4) & 0x07);
    Int_Oled_WriteCmd(bytes, 3);
}

void Int_Oled_ShowStr(u8 x, u8 y, u8 *str)
{
    u8 i;
    // 上半部分
    // 设置页地址和列地址
    Int_Oled_SetPointer(2 * y, 8 * x);
    // 发送数据
    for (i = 0; i < 16 - x && str[i]; i++) {
        Int_Oled_WriteData(Int_Oled_Font[str[i] - 32], 8);
    }

    // 下半部分
    // 设置页地址和列地址
    Int_Oled_SetPointer(2 * y + 1, 8 * x);
    // 发送数据
    for (i = 0; i < 16 - x && str[i]; i++) {
        Int_Oled_WriteData(Int_Oled_Font[str[i] - 32] + 8, 8);
    }
}


void Int_Oled_ShowNum(u8 x, u8 y, long int num)
{
    u8 str[17];
    u8 i = 0;
    u8 j = 0;
    u8 tmp;
    if (num == 0) {
        str[0] = '0';
    } else {
        if (num < 0) {
            str[i++] = '-';
            num      = -num;
            j        = 1;
        }

        // 转换字符串
        while (num) {
            str[i++] = num % 10 + '0';
            num      = num / 10;
        }
        // 字符串终止
        str[i] = 0;
        i--;
        // 反转整个数字
        while (i > j) {
            tmp    = str[i];
            str[i] = str[j];
            str[j] = tmp;
            i--;
            j++;
        }
    }

    Int_Oled_ShowStr(x, y, str);
}

mian.c

#include "Int_Oled.h"

void main()
{
    Int_Oled_Init();
    Int_Oled_Clear();
    Int_Oled_ShowStr(0, 0, "Hello world!");
    Int_Oled_ShowNum(0, 1, 123456);
    while (1) {
    }
}

补充

清屏优化

void Dri_IIC_SendByte(u8 byte)
{
    u8 i;
    for (i = 0; i < 8; i++) {
        SDA = (byte & (0x80 >> i)) == 0 ? 0 : 1;
        SCL = 1;
        SCL = 0;
    }
}

这是I2C中一段代码,现在对其进行优化

void Dri_IIC_SendByte(u8 byte)
{
    u8 i;
    for (i = 0; i < 8; i++) {
        //SDA = (byte & (0x80 >> i)) == 0 ? 0 : 1;
        if ((byte & 0x80) == 0x00) {
            SDA = 0;
        } else {
            SDA = 1;
        }
        byte <<= 1;
        SCL = 1;
        SCL = 0;
    }
}
void Int_Oled_Clear() {
    u8 cmd_bytes[2]={0x20,0x00};
    u8 data_bytes[8] = {0};
    u8 i;
    Int_Oled_WriteCmd(cmd_bytes, 2);
    for ( i = 0; i < 128; i++)
    {
        Int_Oled_WriteData(data_bytes, 8);
    }
}

优化清屏逻辑
原来的逻辑:通过128次循环,每次循环进行1次通信,1次通信写8个字节
现在的逻辑:只进行1次通信,循环写入128*8字节

void Int_Oled_Clear() {
    u8 cmd_bytes[2]={0x20,0x00};
    u8 data_bytes[8] = {0};
    u16 i;
    Int_Oled_WriteCmd(cmd_bytes, 2);
    // for ( i = 0; i < 128; i++)
    // {
    //     Int_Oled_WriteData(data_bytes, 8);
    // }

    // 发送起始信号
    Dri_IIC_Start();
    // 发送设备地址
    Dri_IIC_SendByte(OLED_ADDR);
    Dri_IIC_ReceiveAck();
    // 发送控制字节
    Dri_IIC_SendByte(DATA_MODE);
    Dri_IIC_ReceiveAck();
    // 发送数据
    for (i = 0; i < 128 * 8; i++) {
        Dri_IIC_SendByte(0x00);
        Dri_IIC_ReceiveAck();
    }
    Dri_IIC_Stop();

}

数字展示

使用库函数,将数字转成字符串

#include <STDIO.H>

void Int_Oled_ShowNum(u8 x, u8 y, long int num)
{
    char str[12];
    sprintf(str, "%ld", num);
    Int_Oled_ShowStr(x, y, str);
}

标签:0x08,u8,0x20,0x00,Oled,OLED,0x80,屏幕
From: https://blog.csdn.net/m0_58749949/article/details/144899440

相关文章

  • STM32:OLED(显示屏)开发基础
      思路:了解OLED相关资料----配置参数(OLED底层驱动移植)---编写代码【含例题】---烧入开发板 一、了解OLED相关资料1.什么是OLED?全称:OrganicLight-EmittingDisplay(有机发光二极管),其作用能将电能直接转化为光能的半导体器件,属于电流型的有机发光器件。2.OLED的四个......
  • 移动端数据分析界面,小小屏幕展示大量数据,对设计师是个考验
    移动端数据分析界面确实给设计师带来不小挑战。一方面,屏幕空间有限,要展示海量数据,就得精心规划布局,像用折叠菜单、分层展示等方式,让关键数据优先呈现,同时又能按需查看更多详情。另一方面,要考虑视觉效果,通过合理配色区分不同数据类型,利用图表简洁呈现复杂数据关系,确保清晰易读......
  • Qt监控系统放大招/历经十几年迭代完善/多屏幕辅屏预览/多层级设备树/网络登录和回放
    一、前言说明近期对视频监控系统做了比较大的更新升级,主要就是三点,第一点就是增加了辅屏预览,这个也是好多个客户需要的功能,海康的iVMS-4200客户端就有这个功能,方便在多个屏幕打开不同的视频进行查看,比如有100个通道,如果只是在一个屏幕上查看,那就太小了,而现在很多电脑都是多屏幕,每......
  • CSS将元素完全移出可见屏幕方法有哪些?
    在前端开发中,你可以使用多种CSS方法将元素完全移出可见屏幕。以下是一些常见的方法:使用position和left/top属性:你可以将元素的position设置为absolute或fixed,然后使用left和top属性将其移动到屏幕外部。.element{position:absolute;left:-9999px;top:-9999px;}......
  • 智谱开源 CogAgent-9B,让 AI「看懂」屏幕;Anthropic:大多数任务无需复杂 AI 智能体
      开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(Real-TimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编辑......
  • Linux纯软件Sunshine与Moonlight极低延迟安卓副屏幕解决方案
    Linux纯软件Sunshine与Moonlight极低延迟安卓副屏幕解决方案本文将介绍如何通过Sunshine+Moonlight在Linux下将安卓平板设置为一块极低延迟的扩展屏幕。基于我个人的实际配置,以下是详细步骤和优化方案。硬件环境以下是我的设备配置(仅供参考):OS:ArchLinuxx86_64Hos......
  • ToDesk虚拟屏调整屏幕分辨率,显卡欺骗器、锁屏宝
    ToDesk虚拟屏功能相信很多使用这款软件的小伙伴们或多或少都有听说或尝试过,它的作用可多了,既能充当多任务框扩充器、同时又能充当显卡欺骗器,并且还能作为高级隐私屏、锁屏宝,可谓是一款相当实用的神器!当然,好用有用固然重要,但是用的更加舒服顺手也关键,以下小编就为大家简要介绍一下......
  • 【草履虫也想学会】AI8051U学习历程-第四节-OLED调试
    【草履虫也想学会】AI8051U-四-OLED调试上节学习反思学习目标构建基准工程优化代码管理方式OLED模块驱动函数(调用部分)解析最终现象学习总结上节学习反思在后续实验中仅用点灯无法反映程序运行中各部分参数变化状态。利用可视化的方式,可以便于程序的调试。学习目标......
  • sap ABAP 选择屏幕点击不同按钮隐藏字段
    SELECT-OPTIONS:S_TXT01 FOR vbak-vtweg.PARAMETERS: r_button RADIOBUTTON GROUP rg1USER-COMMAND com DEFAULT 'X' . INITIALIZATION. AT SELECTION-SCREEN. ************************************************************************* AT SELECTION-......
  • 六、STM32的外设OLED屏幕的使用
    介绍:OLED(有机发光二极管)是一种具有低功耗和快速响应特点的显示技术。本章所使用的0.96寸OLED模块,不仅界面占用少,且操作简便,非常适合嵌入式应用。其卓越的显示效果和高效的能源利用,使其成为理想的显示解决方案。阿里云盘分享提取码:c2s8目录一、OLED屏幕图示二、函数......