ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STM8驱动SPI接口OLED

2022-02-27 15:02:50  阅读:257  来源: 互联网

标签:STM8 0x20 0x00 uint8 0x40 SPI OLED 0xFF


由于中景园电子给出的例程不够全面,因此特地花时间重新整理了一下代码,并加上了其他的功能。本文记录了使用模拟四线 SPI 协议驱动 OLED 的代码。

目录

使用软件:IAR FOR STM8

编程方式:固件库

硬件配套:STM8S105C6T6实验板

字模软件:PCtoLCD2002

图片转位图(bmp)格式软件:image2lcd

image

1 oled.h

#ifndef __OLED_SPI_H
#define __OLED_SPI_H

/*******************模拟四线 SPI 驱动 0.96寸OLED(128x64)**********************/

/* Includes ------------------------------------------------------------------*/

#include "stm8s.h"
#include "oled_font.h"

/* Enum ----------------------------------------------------------------------*/

enum page_num {PAGE0 = 0, PAGE1, PAGE2, PAGE3, PAGE4, PAGE5, PAGE6, PAGE7};
enum roll_frame {FRAME0 = 0, FRAME1, FRAME2, FRAME3, FRAME4, FRAME5, FRAME6, FRAME7};

/* Defines -------------------------------------------------------------------*/

#define OLED_CMD            0u          /* 命令模式 */
#define OLED_DATA           1u          /* 数据模式 */

#define OLED_CATHODE        0u          /* 阴码 */
#define OLED_ANODE          1u          /* 阳码 */

#define OLED_FONT_SIZE_12       12
#define OLED_FONT_SIZE_16       16

#define OLED_SCROLL_RIGHT      0u
#define OLED_SCROLL_LEFT       1u

#define OLED_SCK_PORT           (GPIOB) 
#define OLED_SCK_PIN            (GPIO_PIN_5) /* PB5 (OLED_D0)  */

#define OLED_SDA_PORT           (GPIOB) 
#define OLED_SDA_PIN            (GPIO_PIN_4) /* PB4 (OLED_D1)  */

#define OLED_RES_PORT           (GPIOD) 
#define OLED_RES_PIN            (GPIO_PIN_0) /* PD0 (OLED_RES) */

#define OLED_DC_PORT            (GPIOG) 
#define OLED_DC_PIN             (GPIO_PIN_1) /* PG1 (OLED_DC)  */

#define OLED_CS_PORT            (GPIOC) 
#define OLED_CS_PIN             (GPIO_PIN_6) /* PC6 (OLED_CS)  */

#define OLED_SCK_LOW()         GPIO_WriteLow (OLED_SCK_PORT, OLED_SCK_PIN)
#define OLED_SCK_HIGH()        GPIO_WriteHigh(OLED_SCK_PORT, OLED_SCK_PIN)

#define OLED_SDA_LOW()         GPIO_WriteLow (OLED_SDA_PORT, OLED_SDA_PIN)
#define OLED_SDA_HIGH()        GPIO_WriteHigh(OLED_SDA_PORT, OLED_SDA_PIN)

#define OLED_RES_LOW()         GPIO_WriteLow (OLED_RES_PORT, OLED_RES_PIN)
#define OLED_RES_HIGH()        GPIO_WriteHigh(OLED_RES_PORT, OLED_RES_PIN)

#define OLED_DC_CMD()          GPIO_WriteLow (OLED_DC_PORT, OLED_DC_PIN)
#define OLED_DC_DATA()         GPIO_WriteHigh(OLED_DC_PORT, OLED_DC_PIN)

#define OLED_CS_LOW()          GPIO_WriteLow (OLED_CS_PORT, OLED_CS_PIN)
#define OLED_CS_HIGH()         GPIO_WriteHigh(OLED_CS_PORT, OLED_CS_PIN)

/* Functions -----------------------------------------------------------------*/

static void OLED_DLY_ms (uint32_t ms);

static void OLED_SPI_WriteByte (uint8_t mode, uint8_t data);
void OLED_SPI_WriteCmd (uint8_t cmd);
void OLED_SPI_WriteData (uint8_t data);
static void OLED_SPI_GPIO_Init (void);
void OLED_SPI_Init (void);

void OLED_ON (void);
void OLED_OFF (void);

void OLED_Refresh_Gram (void);
void OLED_Clear (void);

static void OLED_DrawPoint (uint8_t x, uint8_t y, uint8_t mode);
static void OLED_Fill (uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t mode);

static void OLED_ShowChar (uint8_t x, uint8_t y, uint8_t ch, uint8_t size, uint8_t mode);
void OLED_ShowString (uint8_t x, uint8_t y, const uint8_t *str, uint8_t size);

static void OLED_ShowChar_CH (uint8_t x, uint8_t y, const uint8_t *str, uint8_t size, uint8_t mode);
void OLED_ShowChinese (uint8_t x, uint8_t y, const uint8_t *str, uint8_t size, uint8_t num);

void OLED_ShowPic (uint8_t x, uint8_t y, const uint8_t *pic, uint8_t width, uint8_t height, uint8_t mode);

void OLED_VerHorScroll (enum page_num start_page, enum page_num end_page, enum roll_frame frame, uint8_t scroll_offset, uint8_t dir);
void OLED_HorScroll (enum page_num start_page, enum page_num end_page, enum roll_frame frame, uint8_t dir);

#endif /* __OLED_SPI_H */

2 oled.c

根据不同函数的功能,分为以下几类:

2.1 与初始化相关的函数

#include "oled_spi.h"

uint8_t OLED_GRAM[128][8];

/*************************************************************************
                        OLED 专用软件延时函数
--------------------------------------------------------------------------
ms:软件延时长度
*************************************************************************/
static void OLED_DLY_ms (uint32_t ms)
{                         
  uint32_t a;
  
  while (ms)
  {    
    a = 200;
    while (a--);
    ms--;
  }
}

/*************************************************************************
                        往 OLED 中写入一字节数据
--------------------------------------------------------------------------
mode:传输模式  data:一字节数据
*************************************************************************/
static void OLED_SPI_WriteByte (uint8_t mode, uint8_t data)
{
  BitStatus bit;
  uint8_t i;
  
  if (mode == OLED_CMD)
  {
    OLED_DC_CMD();
  }
  else
  {
    OLED_DC_DATA();
  }
  
  OLED_SCK_LOW();
  
  for (i = 0; i < 8; i++)
  {
    OLED_SCK_LOW();
    bit = (BitStatus)(data & 0x80);
    
    if (bit == RESET)
    {
      OLED_SDA_LOW();
    }
    else
    {
      OLED_SDA_HIGH();
    }
    
    OLED_SCK_HIGH();
    data <<= 1;
  }
  
  OLED_SCK_HIGH();
  OLED_DC_DATA();
}

/*************************************************************************
                           往 OLED 写入命令字 
--------------------------------------------------------------------------
cmd:命令字
*************************************************************************/
void OLED_SPI_WriteCmd (uint8_t cmd)
{
  OLED_SPI_WriteByte(OLED_CMD, cmd);
}

/*************************************************************************
                          往 OLED 写入数据字  
--------------------------------------------------------------------------
data:数据字
*************************************************************************/
void OLED_SPI_WriteData (uint8_t data)
{
  OLED_SPI_WriteByte(OLED_DATA, data);
}

/*************************************************************************
                          初始化 OLED 引脚  
--------------------------------------------------------------------------
无参数
*************************************************************************/
static void OLED_SPI_GPIO_Init (void)
{
  GPIO_Init(OLED_SCK_PORT, OLED_SCK_PIN, GPIO_MODE_OUT_PP_HIGH_FAST);
  GPIO_Init(OLED_SDA_PORT, OLED_SDA_PIN, GPIO_MODE_OUT_PP_HIGH_FAST);
  GPIO_Init(OLED_RES_PORT, OLED_RES_PIN, GPIO_MODE_OUT_PP_HIGH_FAST);
  GPIO_Init(OLED_DC_PORT,  OLED_DC_PIN,  GPIO_MODE_OUT_PP_HIGH_FAST);
  GPIO_Init(OLED_CS_PORT,  OLED_CS_PIN,  GPIO_MODE_OUT_PP_HIGH_FAST);
}

/*************************************************************************
                            初始化 OLED 
--------------------------------------------------------------------------
无参数
*************************************************************************/
void OLED_SPI_Init (void)
{
  OLED_SPI_GPIO_Init();
  OLED_CS_LOW();
  
  OLED_SCK_HIGH();
  OLED_RES_LOW();
  OLED_DLY_ms (100);
  OLED_RES_HIGH();
  
  OLED_SPI_WriteCmd(0xAE);         // Display Off (0x00)
  OLED_SPI_WriteCmd(0xD5);
  OLED_SPI_WriteCmd(0x80);         // Set Clock as 100 Frames/Sec
  OLED_SPI_WriteCmd(0xA8);
  OLED_SPI_WriteCmd(0x3F);         // 1/64 Duty (0x0F~0x3F)
  OLED_SPI_WriteCmd(0xD3);
  OLED_SPI_WriteCmd(0x00);         // Shift Mapping RAM Counter (0x00~0x3F)
  OLED_SPI_WriteCmd(0x40 | 0x00);  // Set Mapping RAM Display Start Line (0x00~0x3F)
  OLED_SPI_WriteCmd(0x8D);
  OLED_SPI_WriteCmd(0x10 | 0x04);  // Enable Embedded DC/DC Converter (0x00/0x04)
  OLED_SPI_WriteCmd(0x20);
  OLED_SPI_WriteCmd(0x02);         // Set Page Addressing Mode (0x00/0x01/0x02)
  OLED_SPI_WriteCmd(0xA0 | 0x01);  // Set SEG/Column Mapping    
  OLED_SPI_WriteCmd(0xC0);         // Set COM/x Scan Direction   
  OLED_SPI_WriteCmd(0xDA);
  OLED_SPI_WriteCmd(0x02 | 0x10);  // Set Sequential Configuration (0x00/0x10)
  OLED_SPI_WriteCmd(0x81);
  OLED_SPI_WriteCmd(0xCF);         // Set SEG Output Current
  OLED_SPI_WriteCmd(0xD9);
  OLED_SPI_WriteCmd(0xF1);         // Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  OLED_SPI_WriteCmd(0xDB);
  OLED_SPI_WriteCmd(0x40);         // Set VCOM Deselect Level
  OLED_SPI_WriteCmd(0xA4 | 0x00);  // Disable Entire Display On (0x00/0x01)
  OLED_SPI_WriteCmd(0xA6 | 0x00);  // Disable Inverse Display On (0x00/0x01)
  OLED_SPI_WriteCmd(0xAE | 0x01);  // Display On (0x01)
  
  OLED_Clear();         // 清屏
}

初始化 OLED 只需调用:

OLED_SPI_Init();

2.2 唤醒和休眠

/*************************************************************************
                               唤醒 OLED
--------------------------------------------------------------------------
无参数
*************************************************************************/
void OLED_ON (void)
{
  OLED_SPI_WriteCmd(0X8D);  // 设置电荷泵
  OLED_SPI_WriteCmd(0X14);  // 开启电荷泵
  OLED_SPI_WriteCmd(0XAF);  // OLED唤醒
}

/*************************************************************************
                              休眠 OLED
--------------------------------------------------------------------------
无参数
*************************************************************************/
void OLED_OFF (void)
{
  OLED_SPI_WriteCmd(0X8D);  // 设置电荷泵
  OLED_SPI_WriteCmd(0X10);  // 关闭电荷泵
  OLED_SPI_WriteCmd(0XAE);  // OLED休眠
}

2.3 与显示相关的函数

指定位置刷新显示的功能实现有待进一步研究。

注意:不要频繁调用清屏函数 OLED_Clear(),这会导致屏幕刷新过慢或出现重影现象。

/*************************************************************************
                            OLED 刷新显示
--------------------------------------------------------------------------
无参数
*************************************************************************/
void OLED_Refresh_Gram (void)
{   
  uint8_t i, j;
  
  for(i = 0; i < 8; i++)  
  {  
    OLED_SPI_WriteCmd(0xB0 + i);        // 设置页地址(0~7)
    OLED_SPI_WriteCmd(0x00);            // 设置显示位置—列低地址
    OLED_SPI_WriteCmd(0x10);            // 设置显示位置—列高地址 
    
    for(j = 0; j < 128; j++)
    {
      OLED_SPI_WriteData(OLED_GRAM[j][i]);
    }
  }
  
}

/*************************************************************************
                              OLED 清屏
--------------------------------------------------------------------------
无参数
*************************************************************************/
void OLED_Clear (void)
{
  uint8_t i, j;  
    
  for(i = 0; i < 8; i++)
  {
    for(j = 0; j < 128; j++)
    {
      OLED_GRAM[j][i] = 0X00; 
    }
  }
  
  OLED_Refresh_Gram();  // 更新显示
}

/*************************************************************************
                               OLED 画点 
--------------------------------------------------------------------------
x,y:坐标  mode:阳码/阴码填充
*************************************************************************/
static void OLED_DrawPoint (uint8_t x, uint8_t y, uint8_t mode)
{    
  uint8_t pos, bx;
  uint8_t temp = 0;
  
  if (x > 127|| y > 63)         // 超出范围
  {
    return;       
  }
  
  pos = 7 - y / 8;
  bx  = y % 8;
  temp= 1 << (7 - bx);
  
  if (mode == OLED_ANODE)
  {
    OLED_GRAM[x][pos] |= temp;
  }
  else 
  {
    OLED_GRAM[x][pos] &= ~temp;
  }
}

/*************************************************************************
                            OLED 方块填充
--------------------------------------------------------------------------
x1,y1:左上角坐标  x2,y2:右下角坐标  mode:阳码/阴码填充
*************************************************************************/
static void OLED_Fill (uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t mode)  
{      
  uint8_t x, y;  
  
  for (x = x1; x <= x2; x++)
  {
     for (y = y1; y <= y2; y++)
     {
        OLED_DrawPoint (x, y, mode);
     }
  }   
  
  OLED_Refresh_Gram();          // 更新显示
}

需要刷新屏幕时,调用:

OLED_Refresh_Gram ();

需要清屏时,调用:

OLED_Clear ();

2.4 显示 ASCII 字符串

/*************************************************************************
                            OLED 打印一个字符
--------------------------------------------------------------------------
x,y:坐标  ch:字符  size:字符大小  mode:阳码/阴码
*************************************************************************/
static void OLED_ShowChar (uint8_t x, uint8_t y, uint8_t ch, uint8_t size, uint8_t mode)
{
  uint8_t temp;
  uint8_t i, j;
  uint8_t y0;
  uint8_t csize;
  
  y0 = y;
  ch = ch - ' ';
  csize = (size / 8 + ((size % 8) ? 1 : 0) ) * (size / 2);      //得到字体一个字符对应点阵集所占的字节数
  
  for(i = 0; i < csize; i++)
  {
    switch (size)
    {
    case OLED_FONT_SIZE_12:
      temp = ascii_1206[ch][i];
      break;
    case OLED_FONT_SIZE_16:
      temp = ascii_1608[ch][i];
      break;
    default:
      return;
    }
    
    for(j = 0; j < 8; j++)
    {
      if (temp & 0x80)
      {
        OLED_DrawPoint (x, y, mode);
      }
      else 
      {
        OLED_DrawPoint (x, y, !mode);
      }
      
      temp <<= 1;
      y++;
      
      if ((y - y0) == size)
      {
        y = y0;
        x++;
        break;   // 退出循环
      }
      
    } 
  }
}

/*************************************************************************
                           OLED 打印一个字符串 
--------------------------------------------------------------------------
x,y:坐标  str:字符串  size:字符大小
*************************************************************************/
void OLED_ShowString (uint8_t x, uint8_t y, const uint8_t *str, uint8_t size)
{       
  while( (*str <= '~') && (*str >= ' ') )           //判断是不是非法字符!
  {       
    if ( x > (128 - (size / 2)) )
    {
      x = 0;
      y += size;
    }
    
    if ( y > (64 - size) )
    {
      x = 0;
      y = 0;
      OLED_Clear();
    }
    
    OLED_ShowChar (x, y, *str, size, OLED_ANODE);  
    
    x += size / 2;
    str++;
  }  
}   

使用示例:

OLED_ShowString (0, 0, "Welcome To", OLED_FONT_SIZE_16);

2.5 显示中文字符串

注意:传入的参数必须是一个数组的地址,而不是一个中文字符串。这个数组必须存储中文的点阵数据。

/*************************************************************************
                            OLED 打印一个中文字
--------------------------------------------------------------------------
x,y:坐标  *str:中文数组首地址  size:字符大小  mode:阳码/阴码
*************************************************************************/
static void OLED_ShowChar_CH (uint8_t x, uint8_t y, const uint8_t *str, uint8_t size, uint8_t mode)
{
  uint8_t temp;
  uint8_t i, j;
  uint8_t y0;
  uint8_t csize;
  
  y0 = y;
  csize = (size / 8 + ((size % 8) ? 1 : 0) ) * (size / 2);      //得到字体一个字符对应点阵集所占的字节数
  
  for(i = 0; i < csize; i++)
  {
    temp = *(str + i);
    
    for(j = 0; j < 8; j++)
    {
      if (temp & 0x80)
      {
        OLED_DrawPoint (x, y, mode);
      }
      else 
      {
        OLED_DrawPoint (x, y, !mode);
      }
      
      temp <<= 1;
      y++;
      
      if ((y - y0) == size)
      {
        y = y0;
        x++;
        break;   // 退出循环
      }
      
    } 
  }
}

/*************************************************************************
                            OLED 打印一行中文字
--------------------------------------------------------------------------
x,y:坐标  *str:中文数组首地址  size:字符大小  num:多少字  mode:阳码/阴码
*************************************************************************/
void OLED_ShowChinese (uint8_t x, uint8_t y, const uint8_t *str, uint8_t size, uint8_t num)
{
  uint16_t i;
  
  for (i = 0; i < num * 2; i++)
  {       
    if ( x > (128 - (size / 2)) )
    {
      x = 0;
      y += size;
    }
    
    if ( y > (64 - size) )
    {
      x = 0;
      y = 0;
      OLED_Clear();
    }
    
    OLED_ShowChar_CH (x, y, str, size, OLED_ANODE);  
    
    x += size / 2;
    str += size;
  }  
}

使用示例:

OLED_ShowChinese (20, 20, &chinese1_1616[0][0], OLED_FONT_SIZE_16, 4);

2.6 显示图片

注意:传入的参数必须是一个数组的地址。这个数组必须存储 BMP 图片的点阵数据。

/*************************************************************************
                            OLED 打印 BMP 图片
--------------------------------------------------------------------------
x,y:左上角坐标  *bmp:BMP数组首地址  width,height:图片尺寸大小  
*************************************************************************/
void OLED_ShowPic (uint8_t x, uint8_t y, const uint8_t *pic, uint8_t width, uint8_t height, uint8_t mode)
{
  uint16_t i, j, size;
  uint8_t y0;
  uint8_t temp;
  
  if ((x + width > 128) || (y + height > 64))  
    return;    

  size = (uint16_t)( height / 8 + ((height % 8)? 1 : 0) ) * width;
  y0 = y;
  
  for (i = 0; i < size; i++)
  {
    temp = *(pic + i);
    
    for (j = 0; j < 8; j++)
    {
      if (temp & 0x80)
      {
        OLED_DrawPoint (x, y, mode);
      }
      else 
      {
        OLED_DrawPoint (x, y, !mode);
      }
      
      temp <<= 1;
      y++;
      
      if (y - y0 == height)
      {
        y = y0;
        x++;
        break;
      }
      
    }
  }
}

使用示例:

OLED_ShowPic (0, 0, &bmp1[0][0], 114, 64, OLED_CATHODE);

2.7 垂直及水平滚动

注意:

  • 这些函数需要在OLED_Refresh_Gram()后调用,且不能放在 while 循环体内。
  • 由于硬件设计原因,OLED 不能直接做到完全垂直滚动,只能做到垂直+水平滚动的效果。完全垂直滚动的实现有待本人进一步研究。
/*************************************************************************
                            OLED 垂直+水平滚动显示
--------------------------------------------------------------------------
start_page,end_page:起始/终止页地址  frame:滚动步长时间间隔,帧为单位
scroll_offset:垂直滚动偏移(0-63)  dir:滚动方向
--------------------------------------------------------------------------
注意:该函数需要在 OLED_Refresh_Gram 后调用
*************************************************************************/
void OLED_VerHorScroll (enum page_num start_page, enum page_num end_page, enum roll_frame frame, uint8_t scroll_offset, uint8_t dir)
{
  OLED_SPI_WriteCmd (0x2E);             //关闭滚动
  OLED_SPI_WriteCmd (0x29 + dir);       //水平垂直和水平滚动左右 29/2a
  OLED_SPI_WriteCmd (0x00);             //虚拟字节
  OLED_SPI_WriteCmd (start_page);       //起始页  
  OLED_SPI_WriteCmd (frame);            //滚动时间间隔
  OLED_SPI_WriteCmd (end_page);         //终止页
  OLED_SPI_WriteCmd (scroll_offset);    //垂直滚动偏移量
  OLED_SPI_WriteCmd (0x2F);
}

/*************************************************************************
                            OLED 水平滚动显示
--------------------------------------------------------------------------
start_page,end_page:起始/终止页地址  frame:滚动步长时间间隔,帧为单位
dir:滚动方向
--------------------------------------------------------------------------
注意:该函数需要在 OLED_Refresh_Gram 后调用
*************************************************************************/
void OLED_HorScroll (enum page_num start_page, enum page_num end_page, enum roll_frame frame, uint8_t dir)
{
  OLED_SPI_WriteCmd (0x2E);             //关闭滚动
  OLED_SPI_WriteCmd (0x26 + dir);       //水平向左或者右滚动 26/27
  OLED_SPI_WriteCmd (0x00);             //虚拟字节
  OLED_SPI_WriteCmd (start_page);       //起始页
  OLED_SPI_WriteCmd (frame);            //滚动时间间隔
  OLED_SPI_WriteCmd (end_page);         //终止页
  OLED_SPI_WriteCmd (0x00);             //虚拟字节(必须加上)
  OLED_SPI_WriteCmd (0xFF);             //虚拟字节(必须加上)
  OLED_SPI_WriteCmd (0x2F);             //开启滚动
}

使用示例(要放在 while 外面):

// 实现图片的垂直+水平滚动
  OLED_ShowPic (0, 0, &bmp1[0][0], 114, 64, OLED_CATHODE);
  OLED_Refresh_Gram ();
  OLED_VerHorScroll (PAGE2, PAGE7, FRAME7, 0, OLED_SCROLL_LEFT);

3 字模和图片的相关文件

3.1 oled_font.h

#ifndef __OLED_FONT_H
#define __OLED_FONT_H

#include "stm8s.h"

extern const uint8_t ascii_1206[][12];
extern const uint8_t ascii_1608[][16];

extern const uint8_t chinese1_1616[][16];
extern const uint8_t chinese2_1616[][16];

extern const uint8_t bmp1[][16];
extern const uint8_t bmp2[][16];
extern const uint8_t bmp3[][16];

#endif /* __OLED_FONT_H */

3.2 oled_font.c

存储 ASCII 字符,仅展示一部分代码(12x6 的 ASCII 字符):

#include "oled_font.h"

/*********点阵格式:阴码  取模方式:逐列式  取模走向:顺向(高位在前)*********/

const uint8_t ascii_1206[95][12]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x3F,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x00,0x00},/*""",2*/
{0x09,0x00,0x0B,0xC0,0x3D,0x00,0x0B,0xC0,0x3D,0x00,0x09,0x00},/*"#",3*/
{0x18,0xC0,0x24,0x40,0x7F,0xE0,0x22,0x40,0x31,0x80,0x00,0x00},/*"$",4*/
{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
{0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x40,0x20},/*"(",8*/
{0x00,0x00,0x40,0x20,0x20,0x40,0x1F,0x80,0x00,0x00,0x00,0x00},/*")",9*/
{0x09,0x00,0x06,0x00,0x1F,0x80,0x06,0x00,0x09,0x00,0x00,0x00},/*"*",10*/
{0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x00,0x00},/*"+",11*/
{0x00,0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
{0x00,0x20,0x01,0xC0,0x06,0x00,0x38,0x00,0x40,0x00,0x00,0x00},/*"/",15*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"0",16*/
{0x00,0x00,0x10,0x40,0x3F,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"1",17*/
{0x18,0xC0,0x21,0x40,0x22,0x40,0x24,0x40,0x18,0x40,0x00,0x00},/*"2",18*/
{0x10,0x80,0x20,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"3",19*/
{0x02,0x00,0x0D,0x00,0x11,0x00,0x3F,0xC0,0x01,0x40,0x00,0x00},/*"4",20*/
{0x3C,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x23,0x80,0x00,0x00},/*"5",21*/
{0x1F,0x80,0x24,0x40,0x24,0x40,0x34,0x40,0x03,0x80,0x00,0x00},/*"6",22*/
{0x30,0x00,0x20,0x00,0x27,0xC0,0x38,0x00,0x20,0x00,0x00,0x00},/*"7",23*/
{0x1B,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"8",24*/
{0x1C,0x00,0x22,0xC0,0x22,0x40,0x22,0x40,0x1F,0x80,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
{0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40},/*"<",28*/
{0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00},/*"=",29*/
{0x00,0x00,0x40,0x40,0x20,0x80,0x11,0x00,0x0A,0x00,0x04,0x00},/*">",30*/
{0x18,0x00,0x20,0x00,0x23,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"?",31*/
{0x1F,0x80,0x20,0x40,0x27,0x40,0x29,0x40,0x1F,0x40,0x00,0x00},/*"@",32*/
{0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40},/*"A",33*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"B",34*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x80,0x00,0x00},/*"C",35*/
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"D",36*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x40,0x30,0xC0,0x00,0x00},/*"E",37*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x00,0x30,0x00,0x00,0x00},/*"F",38*/
{0x0F,0x00,0x10,0x80,0x20,0x40,0x22,0x40,0x33,0x80,0x02,0x00},/*"G",39*/
{0x20,0x40,0x3F,0xC0,0x04,0x00,0x04,0x00,0x3F,0xC0,0x20,0x40},/*"H",40*/
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x00,0x00},/*"I",41*/
{0x00,0x60,0x20,0x20,0x20,0x20,0x3F,0xC0,0x20,0x00,0x20,0x00},/*"J",42*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x0B,0x00,0x30,0xC0,0x20,0x40},/*"K",43*/
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x00,0x40,0x00,0x40,0x00,0xC0},/*"L",44*/
{0x3F,0xC0,0x3C,0x00,0x03,0xC0,0x3C,0x00,0x3F,0xC0,0x00,0x00},/*"M",45*/
{0x20,0x40,0x3F,0xC0,0x0C,0x40,0x23,0x00,0x3F,0xC0,0x20,0x00},/*"N",46*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"O",47*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"P",48*/
{0x1F,0x80,0x21,0x40,0x21,0x40,0x20,0xE0,0x1F,0xA0,0x00,0x00},/*"Q",49*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x26,0x00,0x19,0xC0,0x00,0x40},/*"R",50*/
{0x18,0xC0,0x24,0x40,0x24,0x40,0x22,0x40,0x31,0x80,0x00,0x00},/*"S",51*/
{0x30,0x00,0x20,0x40,0x3F,0xC0,0x20,0x40,0x30,0x00,0x00,0x00},/*"T",52*/
{0x20,0x00,0x3F,0x80,0x00,0x40,0x00,0x40,0x3F,0x80,0x20,0x00},/*"U",53*/
{0x20,0x00,0x3E,0x00,0x01,0xC0,0x07,0x00,0x38,0x00,0x20,0x00},/*"V",54*/
{0x38,0x00,0x07,0xC0,0x3C,0x00,0x07,0xC0,0x38,0x00,0x00,0x00},/*"W",55*/
{0x20,0x40,0x39,0xC0,0x06,0x00,0x39,0xC0,0x20,0x40,0x00,0x00},/*"X",56*/
{0x20,0x00,0x38,0x40,0x07,0xC0,0x38,0x40,0x20,0x00,0x00,0x00},/*"Y",57*/
{0x30,0x40,0x21,0xC0,0x26,0x40,0x38,0x40,0x20,0xC0,0x00,0x00},/*"Z",58*/
{0x00,0x00,0x00,0x00,0x7F,0xE0,0x40,0x20,0x40,0x20,0x00,0x00},/*"[",59*/
{0x00,0x00,0x70,0x00,0x0C,0x00,0x03,0x80,0x00,0x40,0x00,0x00},/*"\",60*/
{0x00,0x00,0x40,0x20,0x40,0x20,0x7F,0xE0,0x00,0x00,0x00,0x00},/*"]",61*/
{0x00,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10},/*"_",63*/
{0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x02,0x80,0x05,0x40,0x05,0x40,0x03,0xC0,0x00,0x40},/*"a",65*/
{0x20,0x00,0x3F,0xC0,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"b",66*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
{0x00,0x00,0x03,0x80,0x05,0x40,0x05,0x40,0x03,0x40,0x00,0x00},/*"e",69*/
{0x00,0x00,0x04,0x40,0x1F,0xC0,0x24,0x40,0x24,0x40,0x20,0x00},/*"f",70*/
{0x00,0x00,0x02,0xE0,0x05,0x50,0x05,0x50,0x06,0x50,0x04,0x20},/*"g",71*/
{0x20,0x40,0x3F,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"h",72*/
{0x00,0x00,0x04,0x40,0x27,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"i",73*/
{0x00,0x10,0x00,0x10,0x04,0x10,0x27,0xE0,0x00,0x00,0x00,0x00},/*"j",74*/
{0x20,0x40,0x3F,0xC0,0x01,0x40,0x07,0x00,0x04,0xC0,0x04,0x40},/*"k",75*/
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x00,0x40,0x00,0x40,0x00,0x00},/*"l",76*/
{0x07,0xC0,0x04,0x00,0x07,0xC0,0x04,0x00,0x03,0xC0,0x00,0x00},/*"m",77*/
{0x04,0x40,0x07,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"n",78*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"o",79*/
{0x04,0x10,0x07,0xF0,0x04,0x50,0x04,0x40,0x03,0x80,0x00,0x00},/*"p",80*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x50,0x07,0xF0,0x00,0x10},/*"q",81*/
{0x04,0x40,0x07,0xC0,0x02,0x40,0x04,0x00,0x04,0x00,0x00,0x00},/*"r",82*/
{0x00,0x00,0x06,0x40,0x05,0x40,0x05,0x40,0x04,0xC0,0x00,0x00},/*"s",83*/
{0x00,0x00,0x04,0x00,0x1F,0x80,0x04,0x40,0x00,0x40,0x00,0x00},/*"t",84*/
{0x04,0x00,0x07,0x80,0x00,0x40,0x04,0x40,0x07,0xC0,0x00,0x40},/*"u",85*/
{0x04,0x00,0x07,0x00,0x04,0xC0,0x01,0x80,0x06,0x00,0x04,0x00},/*"v",86*/
{0x06,0x00,0x01,0xC0,0x07,0x00,0x01,0xC0,0x06,0x00,0x00,0x00},/*"w",87*/
{0x04,0x40,0x06,0xC0,0x01,0x00,0x06,0xC0,0x04,0x40,0x00,0x00},/*"x",88*/
{0x04,0x10,0x07,0x10,0x04,0xE0,0x01,0x80,0x06,0x00,0x04,0x00},/*"y",89*/
{0x00,0x00,0x04,0x40,0x05,0xC0,0x06,0x40,0x04,0x40,0x00,0x00},/*"z",90*/
{0x00,0x00,0x00,0x00,0x04,0x00,0x7B,0xE0,0x40,0x20,0x00,0x00},/*"{",91*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00},/*"|",92*/
{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
}; 

3.3 oled_font_ch.c

存储中文字符,仅展示 12x12 的中文字符“当前温度 ”:

#include "oled_font.h"

/*********点阵格式:阴码  取模方式:逐列式  取模走向:顺向(高位在前)*********/

// chinese1 = "当前温度"
const uint8_t chinese1_1616[4*2][16] = {
{0x00,0x00,0x02,0x02,0x42,0x22,0x22,0x22,0x1A,0x22,0x02,0x22,0x02,0x22,0xFE,0x22},
{0x02,0x22,0x02,0x22,0x0A,0x22,0x12,0x22,0x63,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"当",0*/

{0x10,0x00,0x10,0x00,0x17,0xFF,0x94,0x90,0x74,0x92,0x14,0x91,0x17,0xFE,0x10,0x00},
{0x10,0x00,0x13,0xF0,0x30,0x02,0xD0,0x01,0x17,0xFE,0x10,0x00,0x10,0x00,0x00,0x00},/*"前",1*/

{0x08,0x20,0x06,0x20,0x40,0x7E,0x31,0x80,0x00,0x02,0x00,0x7E,0x7F,0x42,0x49,0x42},
{0x49,0x7E,0x49,0x42,0x49,0x7E,0x49,0x42,0x7F,0x42,0x00,0x7E,0x00,0x02,0x00,0x00},/*"温",2*/

{0x00,0x02,0x00,0x0C,0x3F,0xF1,0x24,0x01,0x24,0x21,0x24,0x32,0x3F,0xAA,0xA4,0xA4},
{0x64,0xA4,0x24,0xA4,0x3F,0xAA,0x24,0x32,0x24,0x01,0x24,0x01,0x20,0x01,0x00,0x00},/*"度",3*/
};

3.4 oled_bmp.c

该文件用于存储图片数据。需要在软件 image2LCD 中将图片转换为 bmp 格式,再用软件 PCtoLCD2002 将其转换为字模数据。

#include "oled_font.h"

// 64x64
const uint8_t bmp2[][16] = {
{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,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x30,0x40,0x00,0x00,0x00,0x00,0x00},
{0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00},
{0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x07,0xC0,0x00,0x00,0x00},
{0x1E,0x00,0x00,0x07,0x90,0x00,0x00,0x00,0x3E,0x00,0x00,0x07,0xF4,0x00,0x00,0x00},
{0x7E,0x00,0x00,0x07,0x98,0x00,0x00,0x00,0x7E,0x00,0x00,0x07,0xE4,0x00,0x00,0x03},
{0xFE,0x00,0x00,0x07,0xFC,0x00,0x00,0x0F,0xFE,0x00,0x00,0x07,0x7E,0x00,0x00,0x1F},
{0xFE,0x00,0x00,0x0F,0x8B,0x00,0x00,0x3F,0xFE,0x00,0x00,0x03,0x02,0x80,0x07,0xFF},
{0xFE,0x00,0x00,0x1C,0x11,0x00,0x1F,0xFF,0xFE,0x00,0x00,0x30,0x00,0x20,0x3F,0xFF},
{0xFE,0x00,0x00,0x04,0x00,0x40,0x7F,0xFF,0xFE,0x00,0x00,0x10,0x00,0x00,0x7F,0xFF},
{0xFE,0x00,0x00,0xC0,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x01,0xE0,0x00,0x00,0xFF,0xFF},
{0xFF,0x00,0x03,0x80,0x00,0x00,0xC7,0xFF,0xFF,0x00,0x06,0x80,0x00,0x00,0x00,0x3F},
{0xFF,0xC0,0x07,0xF0,0x00,0x00,0x80,0x3F,0xFF,0xF0,0x0D,0xF0,0x00,0x00,0x00,0x1F},
{0xFF,0xFC,0x1F,0xE0,0x00,0x01,0x00,0x1F,0xFF,0xFF,0xC1,0xC8,0x01,0x00,0x00,0x3F},
{0xFF,0xFF,0xFF,0x80,0x02,0x00,0x00,0x3F,0xFF,0xFF,0xF8,0x00,0x0C,0xE4,0x00,0x3F},
{0xFF,0xFF,0xFB,0xFC,0x71,0x88,0x00,0x7F,0xFF,0xFF,0xE0,0x7F,0x83,0x00,0x00,0xFF},
{0xFF,0xFF,0xF0,0xFE,0x04,0x00,0x00,0xFF,0xFF,0xFF,0xFB,0x80,0x00,0x00,0x01,0xFF},
{0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x03,0x8F},
{0xFF,0xFF,0xFC,0x08,0x00,0x00,0x07,0x87,0x7F,0xFE,0xFC,0x03,0xA0,0x00,0x1F,0x8F},
{0x1F,0xFE,0xFE,0x0C,0x40,0x00,0x5F,0xDF,0x0F,0xFF,0xFF,0xF8,0x40,0x00,0x7F,0xFF},
{0x1F,0xFC,0xFF,0xE0,0x00,0x00,0xFF,0xFF,0x1F,0x3E,0xFF,0x40,0x00,0x01,0xFF,0xFF},
{0x1F,0x82,0x63,0x00,0x00,0x03,0xFF,0xFF,0x0F,0x80,0x00,0x00,0x00,0x03,0xFF,0xFF},
{0x03,0x80,0x00,0x00,0x00,0x07,0xFF,0xFF,0x03,0xC0,0x00,0x00,0x00,0x0F,0xFF,0xFF},
{0x01,0xE0,0x00,0x00,0x00,0x0F,0xFF,0xFF,0x01,0xB0,0x00,0x00,0x00,0x1F,0xFF,0xFF},
{0x01,0x8C,0x00,0x00,0x00,0x0F,0xFF,0xFF,0x01,0x80,0x00,0x00,0x00,0x0F,0xFF,0xFF},
{0x00,0x80,0x00,0x00,0x00,0x07,0xFF,0xFC,0x01,0xC0,0x00,0x00,0x00,0x07,0xFF,0xF8},
{0x00,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x58,0x00,0x00,0x00,0x01,0xCF,0xF0},
{0x00,0x20,0x00,0x00,0x00,0x00,0xF7,0xE0,0x00,0x00,0x80,0x00,0x00,0x00,0x3F,0xF0},
{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF},
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF},/*"E:\STM8_Project\555.bmp",0*/
};
---EOF---

标签:STM8,0x20,0x00,uint8,0x40,SPI,OLED,0xFF
来源: https://www.cnblogs.com/Mount256/p/15942308.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有