基于STM32F103C8T6标准库的OLED显示屏中文汉字显示实现_资料编号39

目录

一、所需主要硬件方案

二、电路原理图与实物制作

三、字模取字工具

四、程序设计

[4.1 程序总体结构](#4.1 程序总体结构)

[4.2 主程序设计](#4.2 主程序设计)

[4.3 OLED 驱动程序设计](#4.3 OLED 驱动程序设计)

[4.4 字模数据位置](#4.4 字模数据位置)

五、项目工程文件资料下载方式


演示视频

基于STM32标准库的OLED显示屏中文汉字显示实现

功能简介: 实现基于STM32F103C8T6的OLED中文显示系统。系统 I²C 通信实现 OLED 初始化、字符与汉字显示等功能,并结合字模取字工具生成中文汉字点阵数据,完成中文信息的显示,本系统采用的是标准库C语言程序设计。

所需主要硬件:STM32F103C8T6最小系统板、0.96寸OLED显示屏、电源模块等。

一、所需主要硬件方案

所需主要硬件:STM32F103C8T6最小系统板、0.96寸OLED显示屏、电源模块等。

STM32F103C8T6最小系统板

https://detail.tmall.com/item.htm?ali_refid=a3_430582_1006%3A1256430174%3AH%3ACuqWaG9bmUYoTlT303GNf0r%2F%2Fymqmw0Erxow4qUDZaA%3D%3A0cf1cfc4db45703f050bd37e7a5eecc0&ali_trackid=282_0cf1cfc4db45703f050bd37e7a5eecc0&id=679197366447&mi_id=0000nlsmIFrF-fjh5f6WaXsPG5mCBRyHPSI5VcO4Kt_Ox7E&mm_sceneid=1_0_666480043_0&priceTId=213e08f517670839724436455e1a1d&skuId=5165714562578&spm=a21n57.1.hoverItem.1&utparam=%7B%22aplus_abtest%22%3A%22f7f880a77ddb260f7321518481bf0184%22%7D&xxc=ad_ztc

0.96寸OLED显示屏

https://detail.tmall.com/item.htm?id=42044259331&mi_id=0000U_VHNkP6TNhDzUxVArDC9DBnZkF1e1C2rofqkdyaMjg&spm=tbpc.boughtlist.suborder_itemtitle.1.1f422e8df0GNfG

电源模块

https://item.taobao.com/item.htm?abbucket=1&id=16606969730&mi_id=0000dyYrz_b_NFkyeiBZn6FkpTxl9P9FAbZdIvqc17FEgQ4&ns=1&priceTId=213e01ae17673368357066213e1ad3&spm=a21n57.1.hoverItem.4&utparam=%7B%22aplus_abtest%22%3A%2293ea4ba4fd969057feba379bd2268270%22%7D&xxc=taobaoSearch

二、电路原理图与实物制作

如下为本项目的电路原理图

如下为STM32F103C8T6最小系统板用到的接线,使用PB8和PB9与OLED显示屏进行接线。电源接3.3v和GND共地。

如下为OLED显示屏的四个引脚接线,引脚1接GND共地,引脚2接电源正极3.3V,引脚3为SCL引脚接STM32F103V8T6最小系统板的PB8引脚,引脚4为SDA引脚接STM32F103V8T6最小系统板的PB9引脚。

电源输入模块接俩根线,分别为3.3V和GND。

如下根据电路原理图进行洞洞板接线,制作实物。

电源模块用两根杜邦线引出3.3V和GND到洞洞板,然后用飞线将STM32F103C8T6最小系统板和OLED显示屏的3V3和GND引脚接到电源输入处。

然后拿两根杜邦线,将OLED显示屏的SCL和SDA引脚分别接到STM32F103C8T6最小系统板的PB8和PB9引脚。即可完成洞洞板实物制作。

三、字模取字工具

字模取字工具可在网络获取。或者搜索作者的微信公众号"阿齐Archie",工具下载栏的开发工具选项,自行下载获取"OLED显示屏128x64取字软件"压缩包。(本软件工具,来自网络,仅供参考交流知识学习用途,无其他用途)

双击打开exe文件

弹出如下界面

点击软件界面的"选项"按钮

按照如下字模选项进行配置

在如下红框处输入想要的中文汉字,例如我输入"阿齐"

随后点击"生成字模"按钮

生成如下字模数据

复制代码
 阿(0) 齐(1)

{0x00,0xFE,0x02,0x22,0xDA,0x06,0x00,0xF2,0x12,0x12,0xF2,0x02,0xFE,0x02,0x02,0x00},
{0x00,0xFF,0x08,0x10,0x08,0x07,0x00,0x0F,0x04,0x04,0x4F,0x80,0x7F,0x00,0x00,0x00},//阿0

{0x00,0x04,0x84,0x84,0x4C,0x54,0x25,0x26,0x24,0x54,0x4C,0x84,0x84,0x04,0x00,0x00},
{0x01,0x01,0x80,0x60,0x1F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x01,0x01,0x00},//齐1

随后将字模数据进行简单调整,调整成如下样式:

也就是删除了例如阿字两行中间的"}"和"{"

复制代码
{0x00,0xFE,0x02,0x22,0xDA,0x06,0x00,0xF2,0x12,0x12,0xF2,0x02,0xFE,0x02,0x02,0x00,0x00,0xFF,0x08,0x10,0x08,0x07,0x00,0x0F,0x04,0x04,0x4F,0x80,0x7F,0x00,0x00,0x00},//阿0

{0x00,0x04,0x84,0x84,0x4C,0x54,0x25,0x26,0x24,0x54,0x4C,0x84,0x84,0x04,0x00,0x00,0x01,0x01,0x80,0x60,0x1F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x01,0x01,0x00},//齐1

以上即可完成"阿齐"字模数据的获取

四、程序设计

本系统的软件程序设计基于 STM32F103C8T6 单片机,采用 C 语言进行编写,程序主要由主函数文件和 OLED 显示驱动相关文件构成,通过模块化设计实现 OLED 显示屏的初始化、通信控制以及字符显示功能。

4.1 程序总体结构

本系统的软件工程主要由以下几个源文件和头文件组成:

main.c:系统主程序文件,完成系统初始化及 OLED 显示功能调用;

OLED.c:OLED 显示驱动源文件,实现底层通信与显示控制功能;

OLED.h:OLED 显示驱动头文件,声明 OLED 相关函数接口;

OLED_Font.h:OLED 字模数据文件,用于存储汉字及字符的点阵数据。

主函数负责系统初始化和显示内容的组织,OLED 驱动文件负责底层显示实现,字模文件则为显示内容提供数据支持,各模块之间通过函数接口进行调用,结构清晰,便于维护和扩展

4.2 主程序设计

main.c 是系统的核心控制程序,主要完成以下功能:

系统初始化:在主函数中,首先对 STM32F103C8T6 单片机的系统时钟及相关外设进行初始化配置,为后续程序运行提供稳定的工作环境。

OLED 显示模块初始化:主程序中调用 OLED 初始化函数,对 OLED 显示屏进行初始化设置,包括显示模式、地址设置及显示状态配置,确保 OLED 处于正常工作状态。

显示内容控制 :初始化完成后,主程序通过调用 OLED 显示函数,将指定的字符或汉字数据显示在 OLED 屏幕上。显示的数据来源于 OLED_Font.h 中定义的字模数组。

主循环运行:系统完成初始化与初始显示后,进入主循环。由于本设计以显示功能为主,主循环保持系统稳定运行,确保 OLED 显示内容持续有效。

如下为main.c文件

复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "sys.h"
//#include "usart.h"


/*

***********接线
1.OLED接线:3.3v,SCL-单片机PB8,SDA-单片机PB9
2.LED接线:长-单片机3.3v,短-单片机PA1/PA2
3.KEY接线:PB1+GND,PB11+GND
4.USART1接线:RX-单片机PA9,TX-单片机PA10

本项目用OLED显示屏模块接线,其余四个不用
***********


*/


//extern u8 USART_RX_BUF[USART_REC_LEN];     //串口1接收缓冲,最大USART_REC_LEN个字节  200

//uint8_t keynum;//按键

int main(void)
{
	
	/*模块初始化*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		//设置NVIC中断分组2:2位抢占优先级,2位响应优先级	
	sys_stm32_clock_init(9);    						/* 设置时钟, 72Mhz */
	OLED_Init();										//OLED初始化
//	uart_init(9600);                    				 /* 串口初始化为9600 */
//	LED_Init();
//	Key_Init();
	
	
	/*OLED显示*/
    //显示"阿齐:"
	OLED_ShowChinese(0,0,0,16,1);
	OLED_ShowChinese(16,0,1,16,1);
	OLED_ShowChar(32,0,':',16,1); 
	
	while (1)
	{
		
//	printf("xxx\r\n");//串口1发送数据
		
//	keynum = Key_GetNum();		//获取按键键码
//	if(keynum == 1)			//按键1按下,增加阈值
//	{
	
//	}
//	else if(keynum == 2)	//按键2按下,减小阈值
//	{
		
//	}	
		
		
	}
}

4.3 OLED 驱动程序设计

OLED 显示驱动程序主要用于实现 STM32F103C8T6 与 0.96 寸 OLED 显示屏之间的通信及显示控制。

OLED.c 文件中具体实现了 OLED 显示屏的各项驱动功能,主要包括:

通信控制实现:通过软件方式模拟 I²C 通信时序,利用 STM32F103C8T6 的 PB8 和 PB9 引脚分别作为 SCL 和 SDA,实现与 OLED 显示屏的数据通信。

OLED 初始化函数:驱动程序中按照 OLED 显示屏的工作时序,对其进行初始化配置,包括显示模式、扫描方向及显示开启等操作。

显示控制函数:实现对 OLED 显示缓存的操作,可完成清屏、指定位置显示字符或汉字等功能,为上层应用提供基础显示支持。

OLED 驱动程序采用函数封装的方式,结构清晰,具有良好的可移植性和可读性。

如下为OLED.c文件

复制代码
#include "OLED.h"
#include "stdlib.h"
#include "OLED_Font.h"
#include "Delay.h"


u8 OLED_GRAM[144][8];

//反显函数
void OLED_ColorTurn(u8 i)
{
	if(i==0)
		{
			OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
		}
	if(i==1)
		{
			OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
		}
}

//屏幕旋转180度
void OLED_DisplayTurn(u8 i)
{
	if(i==0)
		{
			OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
			OLED_WR_Byte(0xA1,OLED_CMD);
		}
	if(i==1)
		{
			OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
			OLED_WR_Byte(0xA0,OLED_CMD);
		}
}

//延时
void IIC_delay(void)
{
	u8 t=3;
	while(t--);
}

//起始信号
void OLED_I2C_Start(void)
{
	OLED_SDA_Set();
	OLED_SCL_Set();
	IIC_delay();
	OLED_SDA_Clr();
	IIC_delay();
	OLED_SCL_Clr();
	IIC_delay();
}

//结束信号
void OLED_I2C_Stop(void)
{
	OLED_SDA_Clr();
	OLED_SCL_Set();
	IIC_delay();
	OLED_SDA_Set();
}

//等待信号响应
void OLED_I2C_WaitAck(void) //测数据信号的电平
{
	OLED_SDA_Set();
	IIC_delay();
	OLED_SCL_Set();
	IIC_delay();
	OLED_SCL_Clr();
	IIC_delay();
}

//写入一个字节
void OLED_Send_Byte(u8 dat)
{
	u8 i;
	for(i=0;i<8;i++)
	{
		if(dat&0x80)//将dat的8位从最高位依次写入
		{
			OLED_SDA_Set();
    }
		else
		{
			OLED_SDA_Clr();
    }
		IIC_delay();
		OLED_SCL_Set();
		IIC_delay();
		OLED_SCL_Clr();//将时钟信号设置为低电平
		dat<<=1;
  }
}

//发送一个字节
//mode:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 mode)
{
	OLED_I2C_Start();
	OLED_Send_Byte(0x78);
	OLED_I2C_WaitAck();
	if(mode){OLED_Send_Byte(0x40);}
  else{OLED_Send_Byte(0x00);}
	OLED_I2C_WaitAck();
	OLED_Send_Byte(dat);
	OLED_I2C_WaitAck();
	OLED_I2C_Stop();
}

//开启OLED显示 
void OLED_DisPlay_On(void)
{
	OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
	OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵
	OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕
}

//关闭OLED显示 
void OLED_DisPlay_Off(void)
{
	OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
	OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵
	OLED_WR_Byte(0xAE,OLED_CMD);//关闭屏幕
}

//更新显存到OLED	
void OLED_Refresh(void)
{
	u8 i,n;
	for(i=0;i<8;i++)
	{
		OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址
		OLED_WR_Byte(0x00,OLED_CMD);   //设置低列起始地址
		OLED_WR_Byte(0x10,OLED_CMD);   //设置高列起始地址
		OLED_I2C_Start();
		OLED_Send_Byte(0x78);
		OLED_I2C_WaitAck();
		OLED_Send_Byte(0x40);
		OLED_I2C_WaitAck();
		for(n=0;n<128;n++)
		{
			OLED_Send_Byte(OLED_GRAM[n][i]);
			OLED_I2C_WaitAck();
		}
		OLED_I2C_Stop();
  }
}
//清屏函数
void OLED_Clear(void)
{
	u8 i,n;
	for(i=0;i<8;i++)
	{
	   for(n=0;n<128;n++)
			{
			 OLED_GRAM[n][i]=0;//清除所有数据
			}
  }
	OLED_Refresh();//更新显示
}

//画点 
//x:0~127
//y:0~63
//t:1 填充 0,清空	
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
	u8 i,m,n;
	i=y/8;
	m=y%8;
	n=1<<m;
	if(t){OLED_GRAM[x][i]|=n;}
	else
	{
		OLED_GRAM[x][i]=~OLED_GRAM[x][i];
		OLED_GRAM[x][i]|=n;
		OLED_GRAM[x][i]=~OLED_GRAM[x][i];
	}
//	OLED_Refresh();
}

//画线
//x1,y1:起点坐标
//x2,y2:结束坐标
void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2,u8 mode)
{
	u16 t; 
	int xerr=0,yerr=0,delta_x,delta_y,distance;
	int incx,incy,uRow,uCol;
	delta_x=x2-x1; //计算坐标增量 
	delta_y=y2-y1;
	uRow=x1;//画线起点坐标
	uCol=y1;
	if(delta_x>0)incx=1; //设置单步方向 
	else if (delta_x==0)incx=0;//垂直线 
	else {incx=-1;delta_x=-delta_x;}
	if(delta_y>0)incy=1;
	else if (delta_y==0)incy=0;//水平线 
	else {incy=-1;delta_y=-delta_x;}
	if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴 
	else distance=delta_y;
	for(t=0;t<distance+1;t++)
	{
		OLED_DrawPoint(uRow,uCol,mode);//画点
		xerr+=delta_x;
		yerr+=delta_y;
		if(xerr>distance)
		{
			xerr-=distance;
			uRow+=incx;
		}
		if(yerr>distance)
		{
			yerr-=distance;
			uCol+=incy;
		}
	}
//	OLED_Refresh();
}
//x,y:圆心坐标
//r:圆的半径
void OLED_DrawCircle(u8 x,u8 y,u8 r)
{
	int a, b,num;
    a = 0;
    b = r;
    while(2 * b * b >= r * r)      
    {
        OLED_DrawPoint(x + a, y - b,1);
        OLED_DrawPoint(x - a, y - b,1);
        OLED_DrawPoint(x - a, y + b,1);
        OLED_DrawPoint(x + a, y + b,1);
 
        OLED_DrawPoint(x + b, y + a,1);
        OLED_DrawPoint(x + b, y - a,1);
        OLED_DrawPoint(x - b, y - a,1);
        OLED_DrawPoint(x - b, y + a,1);
        
        a++;
        num = (a * a + b * b) - r*r;//计算画的点离圆心的距离
        if(num > 0)
        {
            b--;
            a--;
        }
    }
//		OLED_Refresh();
}



//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//size1:选择字体 6x8/6x12/8x16/12x24
//mode:0,反色显示;1,正常显示
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode)
{
	u8 i,m,temp,size2,chr1;
	u8 x0=x,y0=y;
	if(size1==8)size2=6;
	else size2=(size1/8+((size1%8)?1:0))*(size1/2);  //得到字体一个字符对应点阵集所占的字节数
	chr1=chr-' ';  //计算偏移后的值
	for(i=0;i<size2;i++)
	{
		if(size1==8)
			  {temp=asc2_0806[chr1][i];} //调用0806字体
		else if(size1==12)
        {temp=asc2_1206[chr1][i];} //调用1206字体
		else if(size1==16)
        {temp=asc2_1608[chr1][i];} //调用1608字体
		else if(size1==24)
        {temp=asc2_2412[chr1][i];} //调用2412字体
		else return;
		for(m=0;m<8;m++)
		{
			if(temp&0x01)OLED_DrawPoint(x,y,mode);
			else OLED_DrawPoint(x,y,!mode);
			temp>>=1;
			y++;
		}
		x++;
		if((size1!=8)&&((x-x0)==size1/2))
		{x=x0;y0=y0+8;}
		y=y0;
  }
	OLED_Refresh();
}


//显示字符串
//x,y:起点坐标  
//size1:字体大小 
//*chr:字符串起始地址 
//mode:0,反色显示;1,正常显示
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode)
{
	while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符!
	{
		OLED_ShowChar(x,y,*chr,size1,mode);
		if(size1==8)x+=6;
		else x+=size1/2;
		chr++;
  }
	OLED_Refresh();
}

//m^n
u32 OLED_Pow(u8 m,u8 n)
{
	u32 result=1;
	while(n--)
	{
	  result*=m;
	}
	return result;
}

//显示数字
//x,y :起点坐标
//num :要显示的数字
//len :数字的位数
//size:字体大小
//mode:0,反色显示;1,正常显示
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1,u8 mode)
{
	u8 t,temp,m=0;
	if(size1==8)m=2;
	for(t=0;t<len;t++)
	{
		temp=(num/OLED_Pow(10,len-t-1))%10;
			if(temp==0)
			{
				OLED_ShowChar(x+(size1/2+m)*t,y,'0',size1,mode);
      }
			else 
			{
			  OLED_ShowChar(x+(size1/2+m)*t,y,temp+'0',size1,mode);
			}
  }
	OLED_Refresh();
}

//显示汉字
//x,y:起点坐标
//num:汉字对应的序号
//mode:0,反色显示;1,正常显示
void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1,u8 mode)
{
	u8 m,temp;
	u8 x0=x,y0=y;
	u16 i,size3=(size1/8+((size1%8)?1:0))*size1;  //得到字体一个字符对应点阵集所占的字节数
	for(i=0;i<size3;i++)
	{
		if(size1==16)
				{temp=Hzk1[num][i];}//调用16*16字体
		else if(size1==24)
				{temp=Hzk2[num][i];}//调用24*24字体
		else if(size1==32)       
				{temp=Hzk3[num][i];}//调用32*32字体
		else if(size1==64)
				{temp=Hzk4[num][i];}//调用64*64字体
		else return;
		for(m=0;m<8;m++)
		{
			if(temp&0x01)OLED_DrawPoint(x,y,mode);
			else OLED_DrawPoint(x,y,!mode);
			temp>>=1;
			y++;
		}
		x++;
		if((x-x0)==size1)
		{x=x0;y0=y0+8;}
		y=y0;
	}
	OLED_Refresh();
}

//num 显示汉字的个数
//space 每一遍显示的间隔
//mode:0,反色显示;1,正常显示
void OLED_ScrollDisplay(u8 num,u8 space,u8 mode)
{
	u8 i,n,t=0,m=0,r;
	while(1)
	{
		if(m==0)
		{
	    OLED_ShowChinese(128,24,t,16,mode); //写入一个汉字保存在OLED_GRAM[][]数组中
			t++;
		}
		if(t==num)
			{
				for(r=0;r<16*space;r++)      //显示间隔
				 {
					for(i=1;i<144;i++)
						{
							for(n=0;n<8;n++)
							{
								OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
							}
						}
           OLED_Refresh();
				 }
        t=0;
      }
		m++;
		if(m==16){m=0;}
		for(i=1;i<144;i++)   //实现左移
		{
			for(n=0;n<8;n++)
			{
				OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
			}
		}
		OLED_Refresh();
	}
}

//x,y:起点坐标
//sizex,sizey,图片长宽
//BMP[]:要写入的图片数组
//mode:0,反色显示;1,正常显示
void OLED_ShowPicture(u8 x,u8 y,u8 sizex,u8 sizey,u8 BMP[],u8 mode)
{
	u16 j=0;
	u8 i,n,temp,m;
	u8 x0=x,y0=y;
	sizey=sizey/8+((sizey%8)?1:0);
	for(n=0;n<sizey;n++)
	{
		 for(i=0;i<sizex;i++)
		 {
				temp=BMP[j];
				j++;
				for(m=0;m<8;m++)
				{
					if(temp&0x01)OLED_DrawPoint(x,y,mode);
					else OLED_DrawPoint(x,y,!mode);
					temp>>=1;
					y++;
				}
				x++;
				if((x-x0)==sizex)
				{
					x=x0;
					y0=y0+8;
				}
				y=y0;
     }
	 }
	OLED_Refresh();
}
//OLED的初始化
void OLED_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
 	RCC_APB2PeriphClockCmd(OLED_SCL_GPIO_CLK|OLED_SDA_GPIO_CLK, ENABLE);	 //使能A端口时钟
	GPIO_InitStructure.GPIO_Pin = OLED_SCL_PIN;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(OLED_SCL_PROT, &GPIO_InitStructure);	  //初始化PA0,1
 	GPIO_SetBits(OLED_SCL_PROT,OLED_SCL_PIN);
	
	GPIO_InitStructure.GPIO_Pin = OLED_SDA_PIN;	
	GPIO_Init(OLED_SDA_PROT, &GPIO_InitStructure);	  //初始化PA0,1
 	GPIO_SetBits(OLED_SDA_PROT,OLED_SDA_PIN);

	Delay_ms(200);
	
	OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
	OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
	OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
	OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
	OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
	OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
	OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
	OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
	OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	OLED_WR_Byte(0x00,OLED_CMD);//-not offset
	OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
	OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
	OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
	OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
	OLED_WR_Byte(0x12,OLED_CMD);
	OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
	OLED_WR_Byte(0x30,OLED_CMD);//Set VCOM Deselect Level
	OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
	OLED_WR_Byte(0x02,OLED_CMD);//
	OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
	OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
	OLED_Clear();
	OLED_WR_Byte(0xAF,OLED_CMD);
}

在 OLED 显示驱动程序中,为实现中文信息的正常显示,系统设计了汉字显示函数 OLED_ShowChinese。该函数基于预先生成的汉字点阵字模数据,实现指定位置、指定字号及显示模式下的单个汉字显示功能,是 OLED 中文显示的核心函数之一。

函数原型如下所示:

复制代码
void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1,u8 mode)

函数功能说明: OLED_ShowChinese 函数主要用于在 0.96 寸 OLED 显示屏上显示单个汉字。函数通过索引字模文件中存储的汉字点阵数据,将对应汉字按照指定的坐标位置写入 OLED 显示缓存,并最终显示在屏幕上。该函数支持不同字号以及正常显示与反色显示两种显示模式,能够满足多种中文显示需求。

参数说明:

x:汉字显示的横坐标起始位置。该参数用于指定汉字在 OLED 显示屏上的起始列坐标,单位为像素点。OLED 屏幕的左上角为坐标原点,不同的 x 值可实现汉字在水平方向上的位置调整。

y:汉字显示的纵坐标起始位置。该参数用于指定汉字在 OLED 显示屏上的起始页地址。由于 OLED 采用分页显示方式,y 的取值通常以页为单位,通过改变该参数可控制汉字在垂直方向上的显示位置。

num:汉字字模序号。该参数用于指定所显示汉字在字模数组中的索引编号。汉字字模数据在 OLED_Font.h 文件中以数组形式顺序存储,num 参数用于准确定位对应汉字的点阵数据,实现正确显示。

size1:汉字字号参数。该参数用于指定汉字的显示尺寸,对应字模数据的点阵大小。通过该参数,函数能够兼容不同规格的汉字字模数据,增强显示的灵活性。

mode:显示模式选择参数。用于设置汉字的显示方式:mode = 1:正常显示模式,按照字模数据原始点阵进行显示;mode = 0:反色显示模式,对字模数据进行取反处理,实现反色显示效果。

函数实现原理说明: 在函数执行过程中,程序首先根据 num 参数从字模数组中读取对应汉字的点阵数据,然后结合 size1 参数确定汉字点阵所占用的显示区域。随后,函数按照 OLED 的页寻址方式,将汉字点阵数据逐字节写入 OLED 显示缓冲区。在写入数据过程中,函数根据 mode 参数判断显示模式,当选择反色显示时,对字模数据进行逻辑取反处理,从而实现反色显示效果。最终,OLED 显示屏完成汉字的正确绘制。

4.4 字模数据位置

OLED_Font.h 文件主要用于存放 OLED 显示所需的字模数据。本系统中的汉字字模数据通过 OLED 字模取字工具生成,并按照 OLED 显示要求进行格式整理后存储在该文件中。

每个汉字的字模数据以数组形式存储,数据内容与 OLED 显示点阵一一对应。主程序在显示汉字时,通过调用 OLED 显示函数,将对应字模数据写入 OLED 显示缓存,从而在屏幕上显示出相应的汉字内容。

通过将字模数据独立存放在专用头文件中,不仅提高了程序的可读性,也便于后续增加或修改显示内容。

五、项目工程文件资料下载方式

下载链接:

基于STM32F103C8T6标准库的OLED显示屏中文汉字显示实现-资料编号39.zip(项目工程文件资料包)资源-CSDN下载https://download.csdn.net/download/m0_61712829/92527814

本项目工程文件资料主要内容:STM32程序源码工程、电路原理图工程、取字软件等资源具体内容以资料包为准。

程序源码工程文件夹如下:

电路原理图工程文件夹如下

本文为项目设计参考文章/案例,演示视频、更多嵌入式项目、项目合集列表、说明链接见开头所示。用户请注意查阅声明/说明。可自行选择付费下载本项目的工程文件,学生可优惠,下方栏可联系。

相关推荐
一路往蓝-Anbo2 小时前
STM32单线串口通讯实战(三):协议层设计 —— 帧结构、多机寻址与硬件唤醒
c语言·开发语言·stm32·单片机·嵌入式硬件·物联网
jiecy2 小时前
IPv6 过渡 - 隧道技术
运维·网络·信息与通信
WX131695189983 小时前
是德科技34461A 34465A 34470A 3458A数字万用表
科技·信息与通信·射频工程
别了,李亚普诺夫3 小时前
DMA学习笔记
笔记·stm32
v先v关v住v获v取3 小时前
天然气管道内检测机器人检测节设计14张cad+三维图+设计说明书
科技·单片机·51单片机
无垠的广袤3 小时前
【上海晶珩睿莓 1 单板计算机】物联网环境监测终端
linux·python·嵌入式硬件·物联网·mqtt·home assistant
先知后行。3 小时前
ModBus协议
嵌入式硬件
冷凝雨12 小时前
复数乘法(C & Simulink)
c语言·开发语言·信号处理·simulink·dsp
IT阳晨。12 小时前
【STM32】天气预报项目
stm32·单片机·嵌入式硬件