STM32 F103C8T6学习笔记9:0.96寸单色OLED显示屏—自由取模显示—显示汉字与图片
今日学习0.96寸单色OLED显示屏的自由取模显示:
宋体汉字比较复杂,常用字符可以直接复制存下来,毕竟只有那么几十个字母字符,但汉字实在太多了,基本不会全部放在单片机里存着,一般用到多少个字就取几个字的模,因此汉字放在这里与自由取模一起讲。
文章提供源码、原理解释、测试工程下载,测试效果图展示。
阅读此文需要确定自己已经理解了OLED基本显示原理,并且会用OLED显示一个字符,不懂基础的可以看我之前的文章:
STM32 F103C8T6学习笔记8:0.96寸单色OLED显示屏显示字符_NULL指向我的博客-CSDN博客
目录
取模软件的使用:
汉字显示函数的编写:
字库取模与函数:
显示程序测试:
显示程序代码:
显示效果图:
整体测试工程下载:
图像显示函数的编写:
图像的取模:
图像打印函数的编写:
程序设计:
显示效果:
测试工程下载:
取模软件的使用:
OLED显示屏 以及 其他许多显示屏 的灵活使用,离不开取模软件,我们也需要学习一下这个取模软件的使用,十分简单,没有软件的可以下载我的测试工程,测试工程里面带有取模软件~~

打开取模软件,首先与我一样进行设置:

现在要对汉字取模,首先新建图像,一般汉字选择16*16点阵区域:

这样模板上就有一块16*16的取模区域了:
但它太小了,不利于绘制,因此可以放大看(多按几下放大格点):

然后点文字输入区,鼠标在输入区空白处右键,选择字体:
一般16*16像素大小的字体要选择12:

此处输入了“我”,然后Ctrl+Enter直接生成:

同时,使用鼠标点击任意黑白色块可以自定义调整这个图像的细节,当然,字模方面系统直接生成的已经比较好了,无需调整,这个调整也是我提一嘴的~~:

最后选择取模方式,C51,这个16*16的字模就在底部生成了,可以直接复制了用了~~:

最后提一嘴,一般用二维数组操作、保存、使用字模~~
汉字显示函数的编写:
字库取模与函数:
char Hzk[][32]={
{0x10,0x10,0x10,0xFF,0x10,0x90,0x00,0x3F,0x48,0x48,0x44,0x44,0x44,0x42,0x70,0x00},
{0x04,0x44,0x82,0x7F,0x01,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00},/*"指",0*/{0x00,0xF8,0x08,0x08,0x0C,0xCA,0x49,0x48,0x48,0xC8,0x08,0x08,0x08,0xF8,0x00,0x00},
{0x00,0xFF,0x00,0x00,0x00,0x1F,0x08,0x08,0x08,0x1F,0x00,0x40,0x80,0x7F,0x00,0x00},/*"向",1*/{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},/*"我",2*/};
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{ u8 t,adder=0;OLED_Set_Pos(x,y); for(t=0;t<16;t++){OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);adder+=1;} OLED_Set_Pos(x,y+1); for(t=0;t<16;t++){ OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);adder+=1;}
}
这要结合字库数组来看,一个16*16像素的字共有32个字符编码,一行16个,在二维数组分俩行存一个字,因此要连传2行二维数组才能将一个汉字的字模传给oled.
显示程序测试:
这里我已经取好了需要显示的字模,然后准备在OLED上显示 “NULL指向我”

显示程序代码:
#include "main.h"int main(void)
{ init_ALL(); //初始化所有函数while(1){OLED_ShowChar(0,0,'N',16);OLED_ShowChar(12,0,'U',16); OLED_ShowChar(24,0,'L',16); OLED_ShowChar(36,0,'L',16); OLED_ShowCHinese(48,0,0);OLED_ShowCHinese(64,0,1); OLED_ShowCHinese(80,0,2);}
}//初始化所有函数:
void init_ALL(void)
{SysTick_Init(72); //初始化滴答计时器
// Timer2_Init(); //初始化定时器2i2c_GPIO_Config(); //IIC初始化 OLED_Init(); //初始化OLED屏幕OLED_Clear(); //清空屏幕数据
}
显示效果图:

整体测试工程下载:
https://download.csdn.net/download/qq_64257614/88232357?spm=1001.2014.3001.5503
图像显示函数的编写:
图像的取模:
现在大部分图像的清晰度像素很高,因此需要一些软件处理一下,降低像素才能取模,这里我使用Photoshop将其像素降为 68*64(至少要比OLED的128*64像素小):

清晰度下降了,但能凑合着看:

然后调整为二阶色:

保存时后缀一定要选.bmp 否则直接改后缀保存位式不会变,取模软件使用时 会直接报错!:


取模软件打开刚才修改好的图:

发现不太理想,尝试人工补足一波 再 生成字模::

像这样存在一纬数组就行:

图像打印函数的编写:
这个图像是68*64的,因此在显示时,Y坐标只能是0开始~
这是一个一个点位传过去显示:
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
//x0 传入图像显示起始点x坐标
//y0 传入图像显示起始点y坐标
//x1 传入图像x横向像素个数 + x0
//y1 传入图像y纵向像素个数 占用的页数
//BMP[] 传入图像数组
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)平移到(60,0)
#include "main.h"uint16_t i;int main(void)
{ init_ALL(); //初始化所有函数while(1){for(i=0;i<60;i++){delay_ms(50);OLED_DrawBMP(i,0,68+i,8,BMP);if(i==59){OLED_Clear(); //清空屏幕数据}}}
}//初始化所有函数:
void init_ALL(void)
{SysTick_Init(72); //初始化滴答计时器
// Timer2_Init(); //初始化定时器2i2c_GPIO_Config(); //IIC初始化 OLED_Init(); //初始化OLED屏幕OLED_Clear(); //清空屏幕数据
}
显示效果:
程序设计的注意点就是要在合适的时机清屏,适当的延时,正确的X,Y坐标等等~~~

测试工程下载:
https://download.csdn.net/download/qq_64257614/88232357?spm=1001.2014.3001.5503
相关文章:
STM32 F103C8T6学习笔记9:0.96寸单色OLED显示屏—自由取模显示—显示汉字与图片
今日学习0.96寸单色OLED显示屏的自由取模显示: 宋体汉字比较复杂,常用字符可以直接复制存下来,毕竟只有那么几十个字母字符,但汉字实在太多了,基本不会全部放在单片机里存着,一般用到多少个字就取几个字的模ÿ…...
直播平台源码搭建协议讲解篇:传输控制协议TCP
简介: 由于直播平台在当今时代发展的越来越迅速,使得直播平台的技术功能越来越智能,让用户在直播平台中能够和其他用户进行实时互动,让用户可以获取到全世界最新的资讯,让一些用户可以作为主播获得工作,让…...
中文编码问题:raw_input输入、文件读取、变量比较等str、unicode、utf-8转换问题
最近研究搜索引擎、知识图谱和Python爬虫比较多,中文乱码问题再次浮现于眼前。虽然市面上讲述中文编码问题的文章数不胜数,同时以前我也讲述过PHP处理数据库服务器中文乱码问题,但是此处还是准备简单做下笔记。方便以后查阅和大家学习。 …...
基于Jenkins自动打包并部署Tomcat环境
目录 1、配置git主机 2、配置jenkins主机 3、配置web主机 4、新建Maven项目 5、验证 Jenkins 自动打包部署结果 Jenkins 的工作原理是先将源代码从 SVN/Git 版本控制系统中拷贝一份到本地,然后根据设置的脚本调用Maven进行 build(构建)。…...
开利网络受邀参与御盛马术庄园发展专委会主题会议
近日,开利网络受邀参与深度合作客户御盛马术庄园组织的首届发展专委会主体会议,就马术庄园发展方向进行沟通,数字化也是重要议题之一。目前,御盛马术庄园已经完成数字化系统的初步搭建,将通过线上线下相结合的方式搭建…...
无类别域间路由(Classless Inter-Domain Routing, CIDR):理解IP网络和子网划分(传统的IP地址类ABCDE:分类网络)
文章目录 无类别域间路由(CIDR):理解IP网络和子网划分引言传统的IP地址类关于“IP地址的浪费” IP地址与CIDRIP地址概述网络号与主机号CIDR记法(网络 网络地址/子网掩码)网络和广播地址 CIDR的优势减少路由表项缓解IP…...
合宙Air724UG LuatOS-Air LVGL API-概念
概念 在 LVGL 中,用户界面的基本构建块是对象。例如,按钮,标签,图像,列表,图表或文本区域。 属性 基本属性 所有对象类型都共享一些基本属性: Position (位置) Size (尺寸) Parent (父母) Cli…...
【C语言】位段,枚举和联合体详解
目录 1.位段 1.1 什么是位段 1.2 位段的内存分配 1.3 位段的跨平台问题 2.枚举 2.1 枚举类型的定义 2.2 枚举的优点 3. 联合(共用体) 3.1 联合类型的定义 3.2 联合的特点 3.3 联合大小的计算 1.位段 1.1 什么是位段 位段的声明和结构体是类…...
python学习-文件管理
文件管理 shutil 文件拷贝 shutil.copy(src,dst) 注:srcrE:\python\.vscode\文件操作 windows上运行时候,如果不加r,上述文件路径在代码运行时会报错,因为其会先将双引号”“去掉,然后系统看到了文件路径中有\nc&…...
【LeetCode 算法】Number of Ways of Cutting a Pizza 切披萨的方案数-记忆化
文章目录 Number of Ways of Cutting a Pizza 切披萨的方案数问题描述:分析代码递归 Tag Number of Ways of Cutting a Pizza 切披萨的方案数 问题描述: 给你一个 rows x cols 大小的矩形披萨和一个整数 k ,矩形包含两种字符: A…...
机器视觉之光流
光流(Optical Flow)是计算机视觉领域的一个重要概念,用于描述图像中物体的运动模式。光流可以用来跟踪图像中物体的运动,检测运动中的物体,或者在机器视觉任务中估计物体的速度和位移。 光流的基本思想是根据图像像素…...
C++:list使用以及模拟实现
list使用以及模拟实现 list介绍list常用接口1.构造2.迭代器3.容量4.访问数据5.增删查改6.迭代器失效 list模拟实现1.迭代器的实现2.完整代码 list介绍 list是一个类模板,加<类型>实例化才是具体的类。list是可以在任意位置进行插入和删除的序列式容器。list的…...
深度学习基础知识-pytorch数据基本操作
1.深度学习基础知识 1.1 数据操作 1.1.1 数据结构 机器学习和神经网络的主要数据结构,例如 0维:叫标量,代表一个类别,如1.0 1维:代表一个特征向量。如 [1.0,2,7,3.4] 2维:就是矩…...
Springboot使用QueryDsl实现融合数据查询
SpringbootQueryDsl技术 1、添加依赖 <!--基于JPA--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!--QueryDSL支持--> <dependenc…...
解决方案 | 电子签打通消费电子行业数智化经营通路
技术迭代不断驱动产业快速增长,从PC电脑到手机平板、再到可穿戴设备的兴起,每一次设备的迭代都代表着技术为产品注入了新的发展动能。与此同时,消费电子设备迭代更新周期的不断缩短,市场增长疲缓等因素,也对行业的流转…...
JVM理论知识
一、JVM内存结构 java的内存模型主要分为5个部分,分别是:JVM堆、JVM栈、本地栈、方法区还有程序计数器,他们的用途分别是: JVM堆:新建的对象都会放在这里,他是JVM中所占内存最大的区域。他又分为新生区还…...
idea - 报错 Mybatis提示Tag name expected的问题< 小于号 无法识别
问题:Mybatis提示Tag name expected 原因: 当我们在mapper中编写sql语句的时候会发现使用"<“符号会提示一个Tag name expected。这是因为xml文件中不识别”<"符号和“&”符号。防止与xml本身的元素命名混淆,导致无法解…...
合宙Air724UG LuatOS-Air LVGL API--对象
对象 概念 在 LVGL 中,用户界面的基本构建块是对象。例如,按钮,标签,图像,列表,图表或文本区域。 属性 基本属性 所有对象类型都共享一些基本属性: Position (位置) Size (尺寸) Parent (父母…...
Java将PDF文件转为Word文档
Java将PDF文件转为Word文档 一、创建Springboot Maven项目 二、导入依赖信息 <repositories><repository><id>com.e-iceblue</id><url>https://repo.e-iceblue.cn/repository/maven-public/</url></repository></repositories&g…...
OpenClaw 深度研究报告:从开源框架到企业级智能体平台的演进之路
一、核心定位:突破"对话天花板"的执行中枢 OpenClaw(外号"龙虾") 是由奥地利工程师 Peter Steinberger 于 2025 年底开发的本地优先、模型无关的 AI 智能体运行框架。其核心价值主张极为鲜明: “The AI that …...
QT 基于qcustomplot实现热力图(四):动态数据流与交互优化实战
1. 动态数据流的核心实现策略 在实时监控系统中,热力图的数据往往需要持续更新。我遇到过不少开发者直接粗暴地全量刷新整个数据集,结果界面卡顿得像老式幻灯片。这里分享三种经过实战检验的动态更新方案,每种都有其适用场景。 增量更新法最适…...
Z-Image-Turbo-辉夜巫女惊艳效果:神社鸟居背景+巫女舞动姿态动态构图
Z-Image-Turbo-辉夜巫女惊艳效果:神社鸟居背景巫女舞动姿态动态构图 想看看AI如何将“辉夜巫女”的古典神秘与神社鸟居的庄严宁静完美融合,并赋予其灵动的舞姿吗?今天,我们就来深度体验一个名为“Z-Image-Turbo-辉夜巫女”的专属…...
快速部署MinerU镜像:开箱即用的PDF提取方案,告别繁琐配置
快速部署MinerU镜像:开箱即用的PDF提取方案,告别繁琐配置 1. 引言:为什么你需要一个“开箱即用”的PDF提取工具? 如果你曾经尝试过从一份复杂的PDF文档里提取文字、表格和公式,你大概率经历过这样的痛苦:…...
小白程序员必看:大模型“语义崩塌”陷阱与收藏攻略!
本文深入解析了“语义崩塌”现象,即在大模型处理海量数据时,向量语义失去区分度导致搜索失效。以斯坦福RAG研究为例,揭示高维空间下“维度灾难”如何导致相关性计算失效,影响企业级应用。文章提出分层检索和基于图谱的检索作为解决…...
什么是焦糖布丁理论?用 JTBD 做软件产品设计的四步法
“焦糖布丁理论”其实是对 Jobs to Be Done(JTBD,待办任务理论) 的一种本土化、形象化的称呼,源自哈佛商学院教授 克莱顿克里斯坦森(Clay Christensen) 在其著作《与运气竞争》(Competing Again…...
Pixel Aurora Engine快速部署:阿里云ECS轻量服务器一键安装脚本
Pixel Aurora Engine快速部署:阿里云ECS轻量服务器一键安装脚本 1. 像素极光引擎简介 Pixel Aurora(像素极光)是一款基于AI扩散模型的高端绘图工作站,采用独特的复古像素游戏风格界面设计。这款创意引擎能够将文字描述转化为极具…...
MiniCPM-o-4.5-nvidia-FlagOS部署运维:使用Docker Compose管理多服务依赖
MiniCPM-o-4.5-nvidia-FlagOS部署运维:使用Docker Compose管理多服务依赖 你是不是也遇到过这种情况?想部署一个AI模型,发现它依赖一堆东西:模型服务本身、数据库、缓存、可能还有别的辅助工具。一个个手动去装、去配置、去启动&…...
RouterOS网桥VLAN实战:从零构建安全隔离的二层虚拟网络
1. VLAN基础与RouterOS网桥概述 刚接触网络管理的朋友可能经常听到"VLAN"这个词,但总觉得它神秘莫测。其实VLAN就像给一栋办公楼划分不同部门:财务部、研发部、市场部各自有独立的办公区域,既保证了隐私安全,又避免了相…...
Java结构化并发崩溃了?手把手教你用VirtualThread+StructuredTaskScope定位线程泄漏与作用域越界(附JDK21真机调试录屏)
第一章:Java结构化并发崩溃了?手把手教你用VirtualThreadStructuredTaskScope定位线程泄漏与作用域越界(附JDK21真机调试录屏)Java 21 正式引入结构化并发(Structured Concurrency),其核心组件 …...
