STM32硬件I2C驱动OLED屏幕

本文基于STM32硬件I2C驱动SSD1306 OLED屏幕,提供完整的代码实现及关键注意事项,适用于128x32或128x64分辨率屏幕。代码通过模块化设计,支持显示字符、数字、汉字及位图,并优化了显存刷新机制。


零、完整代码

完整代码:

1)oled.c

cpp 复制代码
/**
 * @file oled.c
 * @brief OLED显示驱动层,支持SSD1306控制器
 * @details 提供OLED初始化、基本绘图、字符显示、显存刷新等功能
 * @note 本驱动针对128x32分辨率和128x64OLED屏适配,需要修改106-110行的启动参数
 */

#include "oledfont.h"
#include "string.h"
#include "oled.h"
#include "stdlib.h"
#include "main.h"

extern I2C_HandleTypeDef hi2c1; ///< I2C外设句柄

/**
 * @brief OLED绘制位图
 * @param x0 起始列坐标(0~127)
 * @param y0 起始页号(0~3)
 * @param x1 结束列坐标(需大于x0)
 * @param y1 结束页号(需大于y0)
 * @param BMP 位图数据数组指针
 * @note 页号与屏幕行的对应关系:每页8行,128x32屏共4页
 */
void OLED_DrawBMP(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char BMP[])
{
	unsigned int j = 0;
	unsigned char x, y;

	if (y1 % 8 == 0)
		y = y1 / 8;
	else
		y = y1 / 8 + 1;
	for (y = y0; y < y1; y++)
	{
		OLED_Set_Pos(x0, y);
		for (x = x0; x < x1; x++)
		{
			OLED_WR_Byte(BMP[j++], OLED_DATA);
		}
	}
}

// OLED的显存
// 存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
// (128x64显存,8页)
uint8_t OLED_GRAM[128][8];

/**
 * @brief 刷新显存到OLED物理屏幕
 * @details 将GRAM数组内容通过I2C写入OLED的GDDRAM
 */
void OLED_Refresh_Gram(void)
{
	uint8_t i, n;
	for (i = 0; i < 4; i++)
	{ // 仅刷新前4页(原为8)
		OLED_WR_Byte(0xb0 + i, OLED_CMD);
		OLED_WR_Byte(0x00, OLED_CMD);
		OLED_WR_Byte(0x10, OLED_CMD);
		for (n = 0; n < 128; n++)
			OLED_WR_Byte(OLED_GRAM[n][i], OLED_DATA);
	}
}

/**
 * @brief 初始化SSD1306控制器
 * @details 配置显示参数、硬件选项,执行上电序列
 */
void OLED_Init(void)
{
	OLED_WR_Byte(0xAE,OLED_CMD);//关闭显示屏
 
	OLED_WR_Byte(0x40,OLED_CMD);//设置起始行地址
	OLED_WR_Byte(0xB0,OLED_CMD);//设置页面起始地址为页面寻址模式,0-7

	OLED_WR_Byte(0xC8,OLED_CMD);//上下反置关(行重映射),C8,从COM[N-1]扫描到COM0;C0,设置 从COM0扫描到COM[N-1],N为复用率

	OLED_WR_Byte(0x81,OLED_CMD);// 设置对比度
	OLED_WR_Byte(0xff,OLED_CMD);// 选择0xff对比度,选择范围0x00-0xff

	OLED_WR_Byte(0xa1,OLED_CMD);// 左右反置关(段重映射),A0H 设置GDDRAM的COL0映射到驱动器输出SEG0,A1H 设置COL127映射到SEG0

	OLED_WR_Byte(0xa6,OLED_CMD);// 正常显示(1亮0灭)

	OLED_WR_Byte(0xa8,OLED_CMD);//	设置多路传输比率,显示行数
	OLED_WR_Byte(0x1f,OLED_CMD);//  MUX=31	 (显示31行)

	OLED_WR_Byte(0xd3,OLED_CMD);// 设置垂直显示偏移(向上)
	OLED_WR_Byte(0x00,OLED_CMD);// 偏移0行

	OLED_WR_Byte(0xd5,OLED_CMD);// 设置DCLK分频和OSC频率
	OLED_WR_Byte(0xf0,OLED_CMD);// 频率最高

	OLED_WR_Byte(0xd9,OLED_CMD);// 设置预充电的持续时间
	OLED_WR_Byte(0x22,OLED_CMD);

	OLED_WR_Byte(0xda,OLED_CMD);// 设置COM引脚配置
	// 128*32
	OLED_WR_Byte(0x02,OLED_CMD);// 序列COM配置,禁用左右反置
	// 128*64
	// OLED_WR_Byte(0x12, OLED_CMD); // 交替COM,左右不反置

	OLED_WR_Byte(0xdb,OLED_CMD);//调整Vcomh调节器的输出
	OLED_WR_Byte(0x49,OLED_CMD);

	OLED_WR_Byte(0x8d,OLED_CMD);// 启用电荷泵
	OLED_WR_Byte(0x14,OLED_CMD);// 启用电荷泵

	OLED_WR_Byte(0xaf,OLED_CMD);// 开OLED显示
	OLED_Clear();
}

/**
 * @brief 显示单个ASCII字符
 * @param x 列坐标(0-127)
 * @param y 页号(0-3)
 * @param chr 要显示的字符
 * @param Char_Size 字体大小:8或16
 * @note 8像素字体使用6x8点阵,16像素使用8x16点阵
 */
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size)
{
	unsigned char c = 0, i = 0;
	c = chr - ' '; // 得到偏移后的值
	if (x > Max_Column - 1)
	{
		x = 0;
		// 原代码:y += 2(适用于8页,改为y += 1适应4页)
		y = y + 1; // 每页高度为8像素,32行共4页
	}

	if (Char_Size == 16)
	{
		// 16像素字体占2页(原为两行,需确保不超过4页)
		OLED_Set_Pos(x, y);
		for (i = 0; i < 8; i++)
		    OLED_WR_Byte(F8X16[c * 16 + i], OLED_DATA);
		OLED_Set_Pos(x, y + 1);
		for (i = 0; i < 8; i++)
		    OLED_WR_Byte(F8X16[c * 16 + i + 8], OLED_DATA);

	}

	else if (Char_Size == 8)
	{
		OLED_Set_Pos(x, y);
		for (i = 0; i < 6; i++)
			OLED_WR_Byte(F6x8[c][i], OLED_DATA);
	}
}


/**
 * @brief 显示无符号整数
 * @param x,y 起始坐标
 * @param num 要显示的数字(0~4294967295)
 * @param len 显示位数(自动截断高位)
 * @param size2 字体大小(需为8或16)
 */
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size2) // OLED_ShowNum(103,6,t,3,16);//显示ASCII字符的码值
{
	uint8_t t, temp;
	uint8_t enshow = 0;
	for (t = 0; t < len; t++)
	{
		temp = (num / oled_pow(10, len - t - 1)) % 10;
		if (enshow == 0 && t < (len - 1))
		{
			if (temp == 0)
			{
				OLED_ShowChar(x + (size2 / 2) * t, y, ' ', size2);
				continue;
			}
			else
				enshow = 1;
		}
		OLED_ShowChar(x + (size2 / 2) * t, y, temp + '0', size2);
	}
}

/**
 * @brief 计算m的n次方
 * @param m 底数
 * @param n 指数
 * @return m^n的值
 */
uint32_t oled_pow(uint8_t m, uint8_t n)
{
	uint32_t result = 1;
	while (n--)
		result *= m;
	return result;
}

/**
 * @brief 显示字符串
 * @param x,y 起始坐标
 * @param chr 字符串数组指针
 * @param Char_Size 字体大小(8或16)
 * @note 字符串以'\0'结尾,自动计算长度
 */
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t chr[], uint8_t Char_Size)
{
	unsigned char j = 0;
	while (chr[j] != '\0')
	{
		OLED_ShowChar(x, y, chr[j], Char_Size);
		x += 8;
		if (x > Max_Column - 8)
		{
			x = 0;
			y += 2;
		}
		j++;
	}
}

/**
 * @brief 显示汉字
 * @param x,y 起始坐标
 * @param no 汉字索引(0~7)
 * @note 汉字数据存储在ZH数组中,索引范围为0~7
 */
void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no)
{
	uint8_t t, adder = 0;
	OLED_Set_Pos(x, y);
	for (t = 0; t < 16; t++)
	{
		OLED_WR_Byte(ZH[2 * no][t], OLED_DATA);
		adder += 1;
	}
	OLED_Set_Pos(x, y + 1);
	for (t = 0; t < 16; t++)
	{
		OLED_WR_Byte(ZH[2 * no + 1][t], OLED_DATA);
		adder += 1;
	}
}

/**
 * @brief 设置OLED显示位置
 * @param x 列坐标(0~127)
 * @param y 页号(0~3)
 * @note 页号与屏幕行的对应关系:每页8行,128x32屏共4页
 */
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
	OLED_WR_Byte(0xb0 + y, OLED_CMD);
	OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD);
	OLED_WR_Byte((x & 0x0f), OLED_CMD);
}


// 打开OLED显示
void OLED_Display_On(void)
{
	OLED_WR_Byte(0X8D, OLED_CMD); // SET DCDC命令
	OLED_WR_Byte(0X14, OLED_CMD); // DCDC ON
	OLED_WR_Byte(0XAF, OLED_CMD); // DISPLAY ON
}

// 关闭OLED显示
void OLED_Display_Off(void)
{
	OLED_WR_Byte(0X8D, OLED_CMD); // SET DCDC命令
	OLED_WR_Byte(0X10, OLED_CMD); // DCDC OFF
	OLED_WR_Byte(0XAE, OLED_CMD); // DISPLAY OFF
}

/**
 * @brief 清空OLED显示
 * @note 将所有像素设置为0(黑色)
 */
void OLED_Clear(void)
{
	uint8_t i, n;
	for (i = 0; i < 8; i++)
	{
		OLED_WR_Byte(0xb0 + i, OLED_CMD); // 设置页地址(0~7)
		OLED_WR_Byte(0x00, OLED_CMD);	  // 设置显示位置---列低地址
		OLED_WR_Byte(0x10, OLED_CMD);	  // 设置显示位置---列高地址
		for (n = 0; n < 128; n++)
			OLED_WR_Byte(0, OLED_DATA);
	} // 更新显示
}

/**
 * @brief 打开OLED显示
 * @note 将所有像素设置为1(白色)
 */
void OLED_On(void)
{
	uint8_t i, n;
	for (i = 0; i < 8; i++)
	{
		OLED_WR_Byte(0xb0 + i, OLED_CMD); // 设置页地址(0~7)
		OLED_WR_Byte(0x00, OLED_CMD);	  // 设置显示位置---列低地址
		OLED_WR_Byte(0x10, OLED_CMD);	  // 设置显示位置---列高地址
		for (n = 0; n < 128; n++)
			OLED_WR_Byte(1, OLED_DATA);
	} // 更新显示
}

/**
 * @brief 填充OLED显示
 * @param fill_Data 填充数据(0x00或0xFF)
 * @note 0x00填充黑色,0xFF填充白色
 */
void fill_picture(unsigned char fill_Data)
{
	unsigned char m, n;
	for (m = 0; m < 8; m++)
	{
		OLED_WR_Byte(0xb0 + m, 0); // page0-page1
		OLED_WR_Byte(0x00, 0);	   // low column start address
		OLED_WR_Byte(0x10, 0);	   // high column start address
		for (n = 0; n < 128; n++)
		{
			OLED_WR_Byte(fill_Data, 1);
		}
	}
}

/**
 * @brief 写入数据或命令到OLED
 * @param dat 要写入的数据
 * @param cmd 0表示命令,1表示数据
 * @note 通过I2C将数据发送到OLED控制器
 */
void OLED_WR_Byte(uint8_t dat, uint8_t cmd)
{
	static uint8_t cmd_data[2];
	if (cmd == OLED_CMD)
	{
		cmd_data[0] = 0x00;
	}
	else
	{
		cmd_data[0] = 0x40;
	}
	cmd_data[1] = dat;
	HAL_I2C_Master_Transmit(&hi2c1, 0X78, cmd_data, 2, 10);
}

/**
 * @brief 写入I2C命令或数据
 * @param I2C_Command 要写入的命令或数据
 * @note 通过I2C将数据发送到OLED控制器
 */
void Write_IIC_Command(unsigned char I2C_Command) // 写命令
{

	uint8_t *pData;
	pData = &I2C_Command;
	HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, pData, 1, 100);
}

/**
 * @brief 写入I2C数据
 * @param IIC_Data 要写入的数据
 * @note 通过I2C将数据发送到OLED控制器
 */
void Write_IIC_Data(unsigned char IIC_Data) // 写数据
{

	uint8_t *pData;
	pData = &IIC_Data;
	HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, pData, 1, 100);
}

2)oled.h

cpp 复制代码
#ifndef __OLED_H
#define __OLED_H
// #include "sys.h"

#include "main.h"
// OLED模式设置
// 0: 4线串行模式  (模块的BS1,BS2均接GND)
#define OLED_MODE 0
#define X_WIDTH 128
#define Y_WIDTH 32
#define Max_Column 128 // 列
#define Max_Row 32	   // 行

#define SIZE 8
#define XLevelL 0x00
#define XLevelH 0x10

#define Brightness 0xFF

#define OLED_CMD 0	// 写命令
#define OLED_DATA 1 // 写数据

void Write_IIC_Data(unsigned char IIC_Data);
void Write_IIC_Command(unsigned char I2C_Command);
void OLED_WR_Byte(uint8_t dat, uint8_t cmd);
void fill_picture(unsigned char fill_Data);
void OLED_On(void);
void OLED_Clear(void);
void OLED_Display_Off(void);
void OLED_Display_On(void);

void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no);
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t chr[], uint8_t Char_Size);	   // OLED_ShowString(0,0,a,sizeof(a));
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size2); // OLED_ShowNum(103,6,t,3,16);//显示ASCII字符的码值

uint32_t oled_pow(uint8_t m, uint8_t n);
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size);
void OLED_Init(void);
void OLED_Refresh_Gram(void);
void OLED_DrawBMP(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char BMP[]);

/*
x x x x x x x x x x x x x x x x     ==16个字符列   y=0行
x x x x x x x x x x x x x x x x     ==16个字符列   y=1行
x x x x x x x x x x x x x x x x     ==16个字符列   y=2行
x x x x x x x x x x x x x x x x     ==16个字符列   y=3行
x x x x x x x x x x x x x x x x     ==16个字符列   y=4行
x x x x x x x x x x x x x x x x     ==16个字符列   y=5行
x x x x x x x x x x x x x x x x     ==16个字符列   y=6行
x x x x x x x x x x x x x x x x     ==16个字符列   y=7行
*/

#endif

3) oledfont.h

cpp 复制代码
#ifndef __OLEDFONT_H
#define __OLEDFONT_H  
//常用ASCII表
//偏移量32 
//ASCII字符集: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
//PC2LCD2002取模方式设置:阴码+逐列式+顺向+C51格式
//总共:3个字符集(12*12、16*16和24*24),用户可以自行新增其他分辨率的字符集。
//每个字符所占用的字节数为:(size/8+((size%8)?1:0))*(size/2),其中size:是字库生成时的点阵大小(12/16/24...)
 
//12*12 ASCII字符集点阵
const unsigned char F6x8[][6] =		
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};


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


char ZH[][32]={ 

{0x40,0x44,0x54,0x65,0xC6,0x64,0x54,0x44,0x00,0xFC,0x44,0x44,0xC4,0x42,0x40,0x00},
{0x20,0x12,0x4A,0x82,0x7F,0x02,0x0A,0x92,0x60,0x1F,0x00,0x00,0xFF,0x00,0x00,0x00},/*"新",0*/
{0x00,0x20,0x18,0xC7,0x44,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0x04,0x00,0x00},
{0x04,0x04,0x04,0x07,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x00},/*"年",1*/
{0x00,0xE0,0x00,0xFF,0x10,0x20,0x08,0x08,0x08,0xFF,0x08,0x08,0xF8,0x00,0x00,0x00},
{0x01,0x00,0x00,0xFF,0x00,0x81,0x41,0x31,0x0D,0x03,0x0D,0x31,0x41,0x81,0x81,0x00},/*"快",2*/
{0x00,0x00,0xE0,0x9C,0x84,0x84,0x84,0xF4,0x82,0x82,0x83,0x82,0x80,0x80,0x00,0x00},
{0x00,0x20,0x10,0x08,0x06,0x40,0x80,0x7F,0x00,0x00,0x02,0x04,0x08,0x30,0x00,0x00},/*"乐",3*/
{0x40,0x30,0x11,0x96,0x90,0x90,0x91,0x96,0x90,0x90,0x98,0x14,0x13,0x50,0x30,0x00},
{0x04,0x04,0x04,0x04,0x04,0x44,0x84,0x7E,0x06,0x05,0x04,0x04,0x04,0x04,0x04,0x00},/*"学",4*/
{0x80,0x80,0x80,0x80,0xFF,0x80,0x80,0xA0,0x90,0x88,0x84,0x82,0x80,0x80,0x80,0x00},
{0x00,0x00,0x00,0x00,0xFF,0x40,0x21,0x12,0x04,0x08,0x10,0x20,0x20,0x40,0x40,0x00},/*"长",5*/
{0x20,0x24,0x24,0x24,0xFE,0x23,0x22,0x20,0x20,0xFF,0x20,0x22,0x2C,0xA0,0x20,0x00},
{0x00,0x08,0x48,0x84,0x7F,0x02,0x41,0x40,0x20,0x13,0x0C,0x14,0x22,0x41,0xF8,0x00},/*"我",6*/
{0x10,0x0C,0x04,0x24,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x24,0x04,0x14,0x0C,0x00},
{0x00,0x81,0x81,0x41,0x31,0x0F,0x01,0x01,0x01,0x7F,0x81,0x81,0x81,0xF1,0x00,0x00},/*"完",7*/
{0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x08,0x08,0xFF,0x08,0x09,0x0A,0xC8,0x08,0x00},
{0x80,0x60,0x1F,0x00,0x10,0x20,0x1F,0x80,0x40,0x21,0x16,0x18,0x26,0x41,0xF8,0x00},/*"成",8*/
{0x00,0xFC,0x04,0xFC,0x00,0x10,0x10,0xFF,0x90,0xC8,0x09,0x0E,0x08,0xE8,0x08,0x00},
{0x00,0x0F,0x04,0x0F,0x00,0x44,0x82,0x7F,0x00,0x40,0x4F,0x60,0x5C,0x43,0x40,0x00},/*"啦",9*/

{0x10,0x88,0xC4,0x33,0x00,0x20,0x10,0x28,0x24,0xE3,0x24,0x28,0x10,0x20,0x20,0x00},
{0x01,0x00,0xFF,0x00,0x20,0x11,0x0D,0x41,0x81,0x7F,0x01,0x05,0x09,0x31,0x00,0x00},/*"徐",10*/
/* (16 X 16 , 宋体 )*/

{0x00,0xFE,0x22,0xFE,0x00,0xFE,0x22,0xFE,0x00,0xFC,0x16,0x25,0x84,0xFC,0x00,0x00},
{0x60,0x1F,0x22,0xBF,0x40,0x3F,0x82,0xFF,0x00,0x13,0x12,0x12,0x52,0x82,0x7E,0x00},/*"鹏",11*/
/* (16 X 16 , 宋体 )*/

{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x40,0xA0,0x10,0x08,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x10,0x21,0x42,0xF0,0x00},/*"飞",12*/
/* (16 X 16 , 宋体 )*/

//每个字必须带大括号否则显示效果不好
};

#endif

(注:需根据具体硬件调整I2C引脚和屏幕参数)

一、硬件连接

  • OLED屏幕:SSD1306控制器,支持I2C通信。
  • STM32引脚配置
    • SCL:I2C时钟线(如PB6)
    • SDA:I2C数据线(如PB7)
    • I2C地址:0x78(若屏幕带RESET引脚,需额外配置)

二、代码结构

1. 核心文件说明

  • oled.c:驱动层实现,包含初始化、显存管理、字符显示等功能。
  • oled.h:定义宏、函数原型及屏幕参数。
  • oledfont.h:存储ASCII和汉字点阵数据(6x8、8x16字体)。

2. 关键函数解析

  • OLED_Init():初始化SSD1306控制器,配置显示参数。
cpp 复制代码
void OLED_Init(void) {
    OLED_WR_Byte(0xAE, OLED_CMD); // 关闭显示
    OLED_WR_Byte(0xD5, OLED_CMD); // 设置时钟分频
    OLED_WR_Byte(0xA8, OLED_CMD); // 设置复用率
    // ... 其他配置命令
    OLED_Clear();                 // 清屏
}
  • OLED_Refresh_Gram():将显存数据刷新到物理屏幕,通过I2C逐页写入。
  • OLED_ShowChar():显示单个字符,支持8/16像素字体,自动换行。

三、关键实现细节

1. 显存管理

  • 显存数组 :OLED_GRAM[128][8],每页8行,共4页(128x32)或8页(128x64)。
  • 刷新逻辑:仅刷新有效页,减少I2C传输量。
cpp 复制代码
void OLED_Refresh_Gram(void) {
    for (uint8_t i = 0; i < 4; i++) { // 仅刷新前4页
        OLED_Set_Pos(0, i);
        HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, OLED_GRAM[i], 128, 100);
    }
}

2. 字体显示优化

  • ASCII字符 :使用F6x8和F8X16点阵数据,通过偏移量快速定位。
  • 汉字显示:预存储常用汉字点阵(如"新年快乐"),通过索引调用。
cpp 复制代码
void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no) {
    OLED_Set_Pos(x, y);
    for (uint8_t t = 0; t < 16; t++)
        OLED_WR_Byte(ZH[2*no][t], OLED_DATA); // 写入上半部分
    OLED_Set_Pos(x, y+1);
    for (uint8_t t = 0; t < 16; t++)
        OLED_WR_Byte(ZH[2*no+1][t], OLED_DATA); // 写入下半部分
}

四、注意事项(重点!)

头文件包含问题

  • main.c中禁止包含 oledfont.h,否则报错:工程\工程名.axf: Error: L6200E: Symbol F6x8 multiply defined (by gpio.o and main.o).等。
  • 正确做法:仅在oled.c中包含oledfont.h,其他文件通过extern引用。

屏幕参数调整

  • 修改初始化参数 (oled.c第106-110行),否则字符高度异常。
cpp 复制代码
// 128x32屏配置
OLED_WR_Byte(0xDA, OLED_CMD);
OLED_WR_Byte(0x02, OLED_CMD); // COM引脚配置
// 128x64屏需改为:OLED_WR_Byte(0x12, OLED_CMD);

I2C地址与速率

  • 确认OLED的I2C地址(通常为0x78或0x7A)。
  • 调整I2C时钟频率(STM32默认100kHz,SSD1306支持400kHz)。
  • extern I2C_HandleTypeDef hi2c1; ///< I2C外设句柄,根据实际情况改

五、使用示例

显示字符串和数字

cpp 复制代码
OLED_ShowString(0, 0, "Hello World!", 16); // 16像素字体
OLED_ShowNum(0, 2, 2023, 4, 16);          // 显示数字2023

显示自定义位图

cpp 复制代码
const uint8_t BMP[] = {0xFF, 0x81, 0xBD, ...}; // 位图数据
OLED_DrawBMP(0, 0, 128, 4, BMP);              // 全屏显示位图

六、常见问题

  • 屏幕不显示:检查I2C地址、引脚配置及初始化序列。
  • 字符错位 :确认OLED_Set_Pos()的页号与显存对应关系。
  • 刷新闪烁:提高刷新频率(建议200Hz以上),或使用双缓冲机制。

感谢婷婷后援团的小徐同学❤❤❤

相关推荐
易只轻松熊19 分钟前
C++(1):整数常量
开发语言·c++
Dovis(誓平步青云)35 分钟前
精讲C++四大核心特性:内联函数加速原理、auto智能推导、范围for循环与空指针进阶
c语言·开发语言·c++·笔记·算法·学习方法
小石(努力版)40 分钟前
嵌入式STM32学习——振动传感器控制继电器开关灯
stm32·嵌入式硬件·学习
孞㐑¥1 小时前
Linux之进程概念
linux·c++·经验分享·笔记
Ronin-Lotus1 小时前
嵌入式硬件篇---UART
单片机·嵌入式硬件·uart·stm32f103rct6
wen__xvn1 小时前
每日一题洛谷T534125 合数c++
开发语言·c++
茯苓gao2 小时前
stm32 串口通讯 和 USART学习 二(HEX和文本数据包收发)
stm32·嵌入式硬件·学习
Camellia03112 小时前
嵌入式学习--江协51单片机day2
嵌入式硬件·学习·51单片机
wen__xvn2 小时前
每日一题洛谷P8615 [蓝桥杯 2014 国 C] 拼接平方数c++
c++·职场和发展·蓝桥杯
番茄灭世神2 小时前
第31讲 循环缓冲区与命令解析
stm32