STM8驱动0.96寸OLED(12864液晶屏)
Posted Mount256
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM8驱动0.96寸OLED(12864液晶屏)相关的知识,希望对你有一定的参考价值。
由于中景园电子给出的例程不够全面,因此特地花时间重新整理了一下代码,并加上了其他的功能。本文记录了使用模拟四线 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 刷新显示
--------------------------------------------------------------------------
无参数
*************************************************************************/
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);
以上是关于STM8驱动0.96寸OLED(12864液晶屏)的主要内容,如果未能解决你的问题,请参考以下文章
Arduino ESP32 0.96OLED I2C屏幕驱动显示
和12岁小同志搞创客开发:如何驱动 12864 OLED液晶显示屏?
和12岁小同志搞创客开发:如何驱动 12864 OLED液晶显示屏?