当前位置: 首页 > article >正文

1-1 STM32-0.96寸OLED显示与控制

1.0 模块原理图


2.0 0.96OLED简介


资料下载:https://jiangxiekeji.com/download.html

程序介绍:https://jiangxiekeji.com/tutorial/oled.html


SSD1306是一款OLED/PLED点阵显示屏的控制器,可以嵌入在屏幕中,用于执行接收数据、显示存储、扫描刷新等任务

驱动接口:128个SEG引脚和64个COM引脚,对应128x64像素点阵显示屏

内置显示存储器(GDDRAM):128x64 bit(128x8 Byte)SRAM

供电:VDD=1.65~3.3V(IC逻辑),VCC=7~15V(面板驱动)

通信接口:8位6800/8080并行接口,3/4线SPI接口,I2C接口


3.0 SSD1306定义及引脚框图


 4.0 通信接口选择与通信线定义


 图片解读:


5.0 6800并口协议


提到 "6800",最著名的可能是 Motorola 6800 微处理器。这是由摩托罗拉公司在1974年发布的8位微处理器,它在当时的计算机和嵌入式系统中扮演了重要角色。


6.0 8080并口协议



7.0 4线SPI



8.0 3线SPI



9.0 0.96寸显示屏命令表



10.0 开启指令



11.0 IIC通讯协议

注:IIC协议实现参考这一篇文章:STM32 IIC协议实现-CSDN博客 


12.0 程序实现


12.0.1 发送命令

// OLED发送命令
void OLED_WriteCommand(uint8_t command)
{
    IIC_Start();
    IIC_SendByte(0x78);
    IIC_Wait_Ack();
    IIC_SendByte(0x00);
    IIC_Wait_Ack();
    IIC_SendByte(command);
    IIC_Wait_Ack();
    IIC_Stop();
}

12.0.2 发送数据

// OLED发送数据
void OLED_WriteData(uint8_t data)
{
    IIC_Start();
    IIC_SendByte(0x78);
    IIC_Wait_Ack();
    IIC_SendByte(0x40);
    MyI2C_ReceiveAck();
    IIC_SendByte(data);
    IIC_Wait_Ack();
    IIC_Stop();
}

12.0.3 设置显示位置

 注:以上的内容来自元地址设置命令表,表示x坐标的位置和Y坐标的位置

// OLED显示位置
void OLED_SetCursor(uint8_t x, uint8_t page)
{
    // 设置显示的X轴低四位
    OLED_WriteCommand(0x00 | (x & 0x0F));
    // 设置显示的X地址高四位
    OLED_WriteCommand(0x10 | (x & 0xF0) >> 4);
    // 设置显示的页地址
    OLED_WriteCommand(0xB0 | page);
}

12.0.4 初始化OLED

 注:这个操作也就是开启显示器的显示,将显示器从关闭状态转换为打开状态

// 初始化OLED
void OLED_Init(void)
{
    // 初始化IIC
    IIC_Init();

    Delay_ms(100);

    OLED_WriteCommand(0xAE);

    OLED_WriteCommand(0xD5);
    OLED_WriteCommand(0x80);

    OLED_WriteCommand(0xA8);
    OLED_WriteCommand(0x3F);

    OLED_WriteCommand(0xD3);
    OLED_WriteCommand(0x00);

    OLED_WriteCommand(0x40);

    OLED_WriteCommand(0xA1);

    OLED_WriteCommand(0xC8);

    OLED_WriteCommand(0xDA);
    OLED_WriteCommand(0x12);

    OLED_WriteCommand(0x81);
    OLED_WriteCommand(0xCF);

    OLED_WriteCommand(0xD9);
    OLED_WriteCommand(0xF1);

    OLED_WriteCommand(0xDB);
    OLED_WriteCommand(0x30);

    OLED_WriteCommand(0xA4);

    OLED_WriteCommand(0xA6);

    OLED_WriteCommand(0x8D);
    OLED_WriteCommand(0x14);

    OLED_WriteCommand(0xAF);

    Delay_ms(100);
}

12.0.5 清屏函数
// OLED 清屏
void OLED_Clear(void)
{
    for (uint8_t j = 0; j < 8; j++)
    {
        OLED_SetCursor(0, j);
        {
            for (uint8_t i = 0; i < 128; i++)
            {
                OLED_WriteData(0x00);
            }
        }
    }
}

12.0.6 OLED显示字符
// OLED显示字符
void OLED_ShowChar(uint8_t x, uint8_t y, char mChar, uint8_t fontSize)
{
    if (fontSize == 8)
    {
        // 设置起始位置
        OLED_SetCursor(x, y);
        uint8_t i = 0;
        for (i = 0; i < 8; i++)
        {
            // 写入数组指定行的第i个数据
            OLED_WriteData(ascii8x16[mChar - ' '][i]);
        }

        OLED_SetCursor(x, y + 1);
        for (i = 0; i < 8; i++)
        {
            OLED_WriteData(ascii8x16[mChar - ' '][i + 8]);
        }
    }
}

12.0.7 OLED显示字符串
void OLED_ShowString(uint8_t X, uint8_t Page, char *String, uint8_t FontSize)
{
    for (uint8_t i = 0; String[i] != '\0'; i++)
    {
        OLED_ShowChar(X + i * FontSize, Page, String[i], FontSize);
    }
}

12.0.8 OLED显示图片
// OLED显示图片
void OLED_ShowImage(uint8_t x, uint8_t y, uint8_t width, uint8_t height, const uint8_t *Image)
{
    for (uint8_t j = 0; j < height; j++)
    {
        // 设置起始位置
        OLED_SetCursor(x, y + j);
        uint8_t i = 0;
        for (i = 0; i < width; i++)
        {
            // 写入数组指定行的第i个数据
            OLED_WriteData(Image[width * j + i]);
        }
    }
}

/**
 * @brief 补充注释
 * 如果高度是1也就是只有8个像素,也就是只有一页
 * 那么显示一页的数据就是遍历width页就是字符的宽度个字节
 * 然后显示对应的数。
 * 如果高度不仅仅是1而是16,也就是代表这个字符是跨2页进行
 * 写入的,那么就要再加一个for循环对第二页的数据进行写入
 * 也就是第二页开始的字节然后写入【0-9】【】
 *
 */

12.0.9 OLED显示汉字

void OLED_ShowChinese(uint8_t X, uint8_t Page, char *Chinese)
{
    // 第一步:先把传递过来的汉字串,拆分为一个个独立的汉字
    char SigleChinese[4] = {0};
    uint8_t pChinese = 0;
    uint8_t pIndex;

    for (uint8_t i = 0; Chinese[i] != '\0'; i++)
    {
        SigleChinese[pChinese] = Chinese[i];
        pChinese++;

        if (pChinese >= 3)
        {
            pChinese = 0;

            for (pIndex = 0; strcmp(OLED_CF16x16[pIndex].Index, "") != 0; pIndex++)
            {
                if (strcmp(OLED_CF16x16[pIndex].Index, SigleChinese) == 0)
                {
                    break;
                }
            }

            OLED_ShowImage(X + ((i + 1) / 3 - 1) * 16, Page, 16, 2, OLED_CF16x16[pIndex].Data);
        }
    }
}
12.0.10 OLED头文件
#ifndef _OLED_H_
#define _OLED_H_
#include <stdint.h>

// OLED初始化
void OLED_Init(void);

// OLED发送命令
void OLED_WriteCommand(uint8_t command);

// OLED发送数据
void OLED_WriteData(uint8_t data);

// OLED显示位置
void OLED_SetCursor(uint8_t x, uint8_t page);

// OLED 清屏
void OLED_Clear(void);

// OLED显示字符
void OLED_ShowChar(uint8_t x, uint8_t y, char mChar, uint8_t fontSize);

// OLED显示图片
void OLED_ShowImage(uint8_t x, uint8_t y, uint8_t width, uint8_t height, const uint8_t *Image);

// void OLED_ShowChinese(uint8_t x, uint8_t y, char *chinese);

void OLED_ShowChinese(uint8_t X, uint8_t Page, char *Chinese);

void OLED_ShowString(uint8_t X, uint8_t Page, char *String, uint8_t FontSize);

#endif

12.0.11 字符编码

注:该字符编码放在一个单独的C语言文件中

#include <stdint.h>
#include <stdio.h>

const uint8_t ascii8x16[][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, 0x00, 0x00, 0x00, 0x00, /*"!",1*/

        0x00, 0x10, 0x0C, 0x02, 0x10, 0x0C, 0x02, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*""",2*/

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

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

        0xF0, 0x08, 0xF0, 0x80, 0x60, 0x18, 0x00, 0x00,
        0x00, 0x31, 0x0C, 0x03, 0x1E, 0x21, 0x1E, 0x00, /*"%",5*/

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

        0x00, 0x12, 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, 0x00, 0xE0, 0x00, 0x00, 0x00,
        0x00, 0x01, 0x01, 0x01, 0x0F, 0x01, 0x01, 0x01, /*"+",11*/

        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x90, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, /*",",12*/

        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*"-",13*/

        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, /*".",14*/

        0x00, 0x00, 0x00, 0x00, 0xC0, 0x38, 0x04, 0x00,
        0x00, 0x60, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, /*"/",15*/

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

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

        0x00, 0x70, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00,
        0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, /*"2",18*/

        0x00, 0x30, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00,
        0x00, 0x18, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, /*"3",19*/

        0x00, 0x00, 0x80, 0x40, 0x30, 0xF8, 0x00, 0x00,
        0x00, 0x06, 0x05, 0x24, 0x24, 0x3F, 0x24, 0x24, /*"4",20*/

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

        0x00, 0xE0, 0x10, 0x88, 0x88, 0x90, 0x00, 0x00,
        0x00, 0x0F, 0x11, 0x20, 0x20, 0x20, 0x1F, 0x00, /*"6",22*/

        0x00, 0x18, 0x08, 0x08, 0x88, 0x68, 0x18, 0x00,
        0x00, 0x00, 0x00, 0x3E, 0x01, 0x00, 0x00, 0x00, /*"7",23*/

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

        0x00, 0xF0, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00,
        0x00, 0x01, 0x12, 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, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, /*";",27*/

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

        0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
        0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, /*"=",29*/

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

        0x00, 0x70, 0x48, 0x08, 0x08, 0x88, 0x70, 0x00,
        0x00, 0x00, 0x00, 0x30, 0x37, 0x00, 0x00, 0x00, /*"?",31*/

        0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00,
        0x07, 0x18, 0x27, 0x28, 0x2F, 0x28, 0x17, 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, 0x01, 0x3E, 0x01, 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, 0x10, 0x28, 0x28, 0x30, 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*/

        0x08, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x08, 0x00,
        0x00, 0x03, 0x3E, 0x01, 0x3E, 0x03, 0x00, 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, 0x04, 0x38, 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, 0x04, 0x00, 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, 0x00, 0x00, 0x00,
        0x00, 0x19, 0x24, 0x24, 0x12, 0x3F, 0x20, 0x00, /*"a",65*/

        0x10, 0xF0, 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, 0x80, 0x80, 0x80, 0x90, 0xF0, 0x00,
        0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, /*"d",68*/

        0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
        0x00, 0x1F, 0x24, 0x24, 0x24, 0x24, 0x17, 0x00, /*"e",69*/

        0x00, 0x80, 0x80, 0xE0, 0x90, 0x90, 0x20, 0x00,
        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*/

        0x10, 0xF0, 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*/

        0x10, 0xF0, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00,
        0x20, 0x3F, 0x24, 0x06, 0x29, 0x30, 0x20, 0x00, /*"k",75*/

        0x00, 0x10, 0x10, 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, 0x91, 0x20, 0x20, 0x11, 0x0E, 0x00, /*"p",80*/

        0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00,
        0x00, 0x0E, 0x11, 0x20, 0x20, 0x91, 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, 0x10, 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, 0x80, 0x80, 0x80, 0x00,
        0x00, 0x03, 0x0C, 0x30, 0x0C, 0x03, 0x00, 0x00, /*"v",86*/

        0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80,
        0x01, 0x0E, 0x30, 0x0C, 0x07, 0x38, 0x06, 0x01, /*"w",87*/

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

        0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80,
        0x00, 0x81, 0x86, 0x78, 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, 0x00, 0xFC, 0x02, 0x02,
        0x00, 0x00, 0x00, 0x00, 0x01, 0x3E, 0x40, 0x40, /*"{",91*/

        0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, /*"|",92*/

        0x02, 0x02, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x40, 0x40, 0x3E, 0x01, 0x00, 0x00, 0x00, 0x00, /*"}",93*/

        0x00, 0x02, 0x01, 0x02, 0x02, 0x04, 0x02, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"~",94*/
};

13.0 主函数文件

#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "IIC_Drv.h"
#include "LED.h"
#include "MyI2C.h"
#include "OLED.h"

const uint8_t Img[] =
	{
		0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00,
		0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, /*"n",78*/
};

const uint8_t Image[] =
{
		0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0xB0, 0xF0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61,
		0xF9, 0x8F, 0x83, 0x01, 0xE1, 0x39, 0x0D, 0x07, 0x21, 0x21, 0x21, 0x21, 0x23, 0x22, 0x20, 0x20, 0xFE, 0x23, 0x31, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x31, 0x1F, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x08, 0x0E, 0x38, 0x60, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"未命名文件",0*/
};

const uint8_t Hao[] =
	{
		0x10, 0x10, 0xF0, 0x1F, 0x10, 0xF0, 0x00, 0x80, 0x82, 0x82, 0xE2, 0x92, 0x8A, 0x86, 0x80, 0x00, 0x40, 0x22, 0x15, 0x08, 0x16, 0x61, 0x00, 0x00, 0x40, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, /*"好",0*/
};

// const uint8_t MyChar[][32] =
// {
// 		0x00, 0x80, 0x60, 0xF8, 0x07, 0x40, 0x20, 0x18, 0x0F, 0x08, 0xC8, 0x08, 0x08, 0x28, 0x18, 0x00, 0x01, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x0C, 0x03, 0x40, 0x80, 0x7F, 0x00, 0x01, 0x06, 0x18, 0x00,
// 		/*"你",0*/

// 		0x10, 0x10, 0xF0, 0x1F, 0x10, 0xF0, 0x00, 0x80, 0x82, 0x82, 0xE2, 0x92, 0x8A, 0x86, 0x80, 0x00, 0x40, 0x22, 0x15, 0x08, 0x16, 0x61, 0x00, 0x00, 0x40, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
// 		/*"好",1*/

// 		0x20, 0x20, 0x20, 0xFE, 0x20, 0x20, 0xFF, 0x20, 0x20, 0x20, 0xFF, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x47, 0x44, 0x44, 0x44, 0x47, 0x40, 0x40, 0x40, 0x00, 0x00,
// 		/*"世",2*/

// 		0x00, 0x00, 0x00, 0xFE, 0x92, 0x92, 0x92, 0xFE, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x84, 0x62, 0x1E, 0x01, 0x00, 0x01, 0xFE, 0x02, 0x04, 0x04, 0x08, 0x08, 0x00,
// 		/*"界",3*/
// };

extern const uint8_t ascii8x16[][16];

int main(void)
{
	OLED_Init();
	OLED_Clear();

	// OLED_ShowChar(20, 1, 'X', 8);

	// OLED_ShowString(0, 0, "helloword!", 8);

	// OLED_ShowImage(0, 0, 8, 2, Img);

	// OLED_ShowImage(0, 0, 8, 2, ascii8x16[4]);

	// OLED_ShowImage(10, 5, 30, 4, Image);

	// OLED_ShowImage(0, 0, 16, 2, Hao);

	// OLED_ShowImage(20, 1, 16, 2, MyChar[3]);

	OLED_ShowChinese(10, 2, "你好世界");

	while (1)
	{
	}
}

OLED_C文件

#include "stm32f10x.h"
#include "MyI2C.h"
#include "IIC_Drv.h"
#include "Delay.h"
#include "OLED.h"
#include <string.h>

extern const uint8_t ascii8x16[][16];

typedef struct {
	char Index[6];
	uint8_t Data[32];
} ChineseCell_t;

const ChineseCell_t OLED_CF16x16[] = {
	
	"你",
	0x00,0x80,0x60,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,
	0x01,0x00,0x00,0xFF,0x00,0x10,0x0C,0x03,0x40,0x80,0x7F,0x00,0x01,0x06,0x18,0x00,/*0*/

	"好",
	0x10,0x10,0xF0,0x1F,0x10,0xF0,0x00,0x80,0x82,0x82,0xE2,0x92,0x8A,0x86,0x80,0x00,
	0x40,0x22,0x15,0x08,0x16,0x61,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,/*1*/

	"世",
	0x20,0x20,0x20,0xFE,0x20,0x20,0xFF,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0x00,
	0x00,0x00,0x00,0x7F,0x40,0x40,0x47,0x44,0x44,0x44,0x47,0x40,0x40,0x40,0x00,0x00,/*2*/

	"界",
	0x00,0x00,0x00,0xFE,0x92,0x92,0x92,0xFE,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,0x00,
	0x08,0x08,0x04,0x84,0x62,0x1E,0x01,0x00,0x01,0xFE,0x02,0x04,0x04,0x08,0x08,0x00,/*3*/
	
	//...
	
	"",
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};

// OLED发送命令
void OLED_WriteCommand(uint8_t command)
{
    IIC_Start();
    IIC_SendByte(0x78);
    IIC_Wait_Ack();
    IIC_SendByte(0x00);
    IIC_Wait_Ack();
    IIC_SendByte(command);
    IIC_Wait_Ack();
    IIC_Stop();
}

// OLED发送数据
void OLED_WriteData(uint8_t data)
{
    IIC_Start();
    IIC_SendByte(0x78);
    IIC_Wait_Ack();
    IIC_SendByte(0x40);
    MyI2C_ReceiveAck();
    IIC_SendByte(data);
    IIC_Wait_Ack();
    IIC_Stop();
}

// OLED显示位置
void OLED_SetCursor(uint8_t x, uint8_t page)
{
    // 设置显示的X轴低四位
    OLED_WriteCommand(0x00 | (x & 0x0F));
    // 设置显示的X地址高四位
    OLED_WriteCommand(0x10 | (x & 0xF0) >> 4);
    // 设置显示的页地址
    OLED_WriteCommand(0xB0 | page);
}

// 初始化OLED
void OLED_Init(void)
{
    // 初始化IIC
    IIC_Init();

    Delay_ms(100);

    OLED_WriteCommand(0xAE);

    OLED_WriteCommand(0xD5);
    OLED_WriteCommand(0x80);

    OLED_WriteCommand(0xA8);
    OLED_WriteCommand(0x3F);

    OLED_WriteCommand(0xD3);
    OLED_WriteCommand(0x00);

    OLED_WriteCommand(0x40);

    OLED_WriteCommand(0xA1);

    OLED_WriteCommand(0xC8);

    OLED_WriteCommand(0xDA);
    OLED_WriteCommand(0x12);

    OLED_WriteCommand(0x81);
    OLED_WriteCommand(0xCF);

    OLED_WriteCommand(0xD9);
    OLED_WriteCommand(0xF1);

    OLED_WriteCommand(0xDB);
    OLED_WriteCommand(0x30);

    OLED_WriteCommand(0xA4);

    OLED_WriteCommand(0xA6);

    OLED_WriteCommand(0x8D);
    OLED_WriteCommand(0x14);

    OLED_WriteCommand(0xAF);

    Delay_ms(100);
}

// OLED 清屏
void OLED_Clear(void)
{
    for (uint8_t j = 0; j < 8; j++)
    {
        OLED_SetCursor(0, j);
        {
            for (uint8_t i = 0; i < 128; i++)
            {
                OLED_WriteData(0x00);
            }
        }
    }
}

// OLED显示字符
void OLED_ShowChar(uint8_t x, uint8_t y, char mChar, uint8_t fontSize)
{
    if (fontSize == 8)
    {
        // 设置起始位置
        OLED_SetCursor(x, y);
        uint8_t i = 0;
        for (i = 0; i < 8; i++)
        {
            // 写入数组指定行的第i个数据
            OLED_WriteData(ascii8x16[mChar - ' '][i]);
        }

        OLED_SetCursor(x, y + 1);
        for (i = 0; i < 8; i++)
        {
            OLED_WriteData(ascii8x16[mChar - ' '][i + 8]);
        }
    }
}

// OLED显示字符串
// void OLED_ShowString(uint8_t x, uint8_t y, char *string, uint8_t fontSize)
// {
//     uint8_t i = 0;
//     for (i = 0; string[i] != '\0'; i++)
//     {
//         // 每个字符对应的起始坐标等于最初的起始坐标,
//         OLED_ShowChar(x + i * fontSize, y, string[i], fontSize);
//     }
// }
void OLED_ShowString(uint8_t X, uint8_t Page, char *String, uint8_t FontSize)
{
    for (uint8_t i = 0; String[i] != '\0'; i++)
    {
        OLED_ShowChar(X + i * FontSize, Page, String[i], FontSize);
    }
}

// OLED显示图片
void OLED_ShowImage(uint8_t x, uint8_t y, uint8_t width, uint8_t height, const uint8_t *Image)
{
    for (uint8_t j = 0; j < height; j++)
    {
        // 设置起始位置
        OLED_SetCursor(x, y + j);
        uint8_t i = 0;
        for (i = 0; i < width; i++)
        {
            // 写入数组指定行的第i个数据
            OLED_WriteData(Image[width * j + i]);
        }
    }
}
/**
 * @brief 补充注释
 * 如果高度是1也就是只有8个像素,也就是只有一页
 * 那么显示一页的数据就是遍历width页就是字符的宽度个字节
 * 然后显示对应的数。
 * 如果高度不仅仅是1而是16,也就是代表这个字符是跨2页进行
 * 写入的,那么就要再加一个for循环对第二页的数据进行写入
 * 也就是第二页开始的字节然后写入【0-9】【】
 *
 */

// void OLED_ShowChinese(uint8_t x, uint8_t y, char *chinese)
// {
//     // 第一步:先把传递过来的汉字串,拆分为一个个独立的汉字
//     char SigleChinese[4] = {0};
//     uint8_t pChinese = 0;

//     // 定义一个变量用于存放索引
//     uint8_t pIndex;

//     // 第二步:遍历汉字字模,一一匹配汉字索引
//     for (uint8_t i = 0; chinese[i] != '\0'; i++)
//     {
//         SigleChinese[pChinese] = chinese[i];
//         pChinese++;

//         if (pChinese >= 3)
//         {
//             pChinese = 0;

//             for (pIndex = 0; strcmp(OLED_CF16X16[pIndex].Index, "") != 0; pIndex++)
//             {
//                 if (strcmp(OLED_CF16X16[pIndex].Index, SigleChinese) == 0)
//                 {
//                     break;
//                 }
//             }
//             // 第三步:取出指定位置的字模数据
//             OLED_ShowImage(x + ((i + 1) / 3 - 1) * 16, y, 16, 2, OLED_CF16X16[pIndex].Data);
//         }
//     }
// }

void OLED_ShowChinese(uint8_t X, uint8_t Page, char *Chinese)
{
    char SigleChinese[4] = {0};
    uint8_t pChinese = 0;
    uint8_t pIndex;

    for (uint8_t i = 0; Chinese[i] != '\0'; i++)
    {
        SigleChinese[pChinese] = Chinese[i];
        pChinese++;

        if (pChinese >= 3)
        {
            pChinese = 0;

            for (pIndex = 0; strcmp(OLED_CF16x16[pIndex].Index, "") != 0; pIndex++)
            {
                if (strcmp(OLED_CF16x16[pIndex].Index, SigleChinese) == 0)
                {
                    break;
                }
            }

            OLED_ShowImage(X + ((i + 1) / 3 - 1) * 16, Page, 16, 2, OLED_CF16x16[pIndex].Data);
        }
    }
}

OLED_H文件:

#ifndef _OLED_H_
#define _OLED_H_
#include <stdint.h>

// OLED初始化
void OLED_Init(void);

// OLED发送命令
void OLED_WriteCommand(uint8_t command);

// OLED发送数据
void OLED_WriteData(uint8_t data);

// OLED显示位置
void OLED_SetCursor(uint8_t x, uint8_t page);

// OLED 清屏
void OLED_Clear(void);

// OLED显示字符
void OLED_ShowChar(uint8_t x, uint8_t y, char mChar, uint8_t fontSize);

// OLED显示图片
void OLED_ShowImage(uint8_t x, uint8_t y, uint8_t width, uint8_t height, const uint8_t *Image);

// void OLED_ShowChinese(uint8_t x, uint8_t y, char *chinese);

void OLED_ShowChinese(uint8_t X, uint8_t Page, char *Chinese);

void OLED_ShowString(uint8_t X, uint8_t Page, char *String, uint8_t FontSize);

#endif

编译以上程序输出如下结果:


...


http://www.kler.cn/a/444273.html

相关文章:

  • 感受野如何计算?
  • LLaMA-Factory 单卡3080*2 deepspeed zero3 微调Qwen2.5-7B-Instruct
  • 有监督学习 vs 无监督学习:机器学习的两大支柱
  • OpenHarmony-4.HDI 框架
  • 使用 esrally race 测试 Elasticsearch 性能:实践指南
  • 【Datawhale AI 冬令营】如何动手微调出自己的大模型
  • linux 安装jdk
  • leetcode----mysql
  • SpringMVC 学习笔记
  • 滑不动窗口的秘密—— “滑动窗口“算法 (Java版)
  • mac iterm2 使用 lrzsz
  • 微积分复习笔记 Calculus Volume 2 - 4.4 The Logistic Equation
  • 浏览器引入elasticsearch-head插件
  • tomcat(Web应用服务器)
  • 线性代数基础与应用:基底 (Basis) 与现金流及单期贷款模型(中英双语)
  • ACL-2024 | MapGPT:基于地图引导提示和自适应路径规划机制的视觉语言导航
  • 如何实现单例模式?
  • webpack处理图片资源
  • 【JavaEE进阶】关于Maven
  • macos控制台安装
  • C++ OpenGL学习笔记(1、Hello World空窗口程序)
  • 计算机网络-GRE Over IPSec实验
  • 递归读取指定目录下的文件
  • postman免登录步骤
  • AIGC:图像风格迁移技术实现猜想
  • 【多模态】MiniCPM-V多模态大模型使用学习