STM8驱动SPI接口OLED
由于中景园电子给出的例程不够全面,因此特地花时间重新整理了一下代码,并加上了其他的功能。本文记录了使用模拟四线 SPI 协议驱动 OLED 的代码。
目录
使用软件:IAR FOR STM8
编程方式:固件库
硬件配套:STM8S105C6T6实验板
字模软件:PCtoLCD2002
图片转位图(bmp)格式软件:image2lcd
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*/
};