STM32标准库驱动W25Q64模块读写字库数据+OLED0.96显示例程
STM32标准库驱动W25Q64 模块读写字库数据+OLED0.96显示例程
- 🎬原创作者对W25Q64保存汉字字库演示:
W25Q64保存汉字字库
- 🎞测试字体显示效果:


📑功能实现说明
利用W25Q64保存汉字字库,OLED显示汉字的时候,先通过SPI接口访问W25Q64,先将要显示的汉子字模数据,从SPI FLASH中读取出来,然后再显示到OLED屏幕上。
🛠W25Q64字库制作
- 🍁W25Q64原理图:

- 👉按照原创作者的思路制作SPI flash字库,需要准备一块足够大的字库SPI flash芯片以及flash足够大的MCU才行。这里选择:W25Q64 + STM32F103VET6
- 🔱如果手上没有这么大的容量的mcu,可以选择使用SPI FLASH编程器单独烧录字库文件。(下面会提供本例程的单独的字库烧录文件.bin文件)前提是手上需要有一个SPI FLASH编程器。(SPI FLASH编程器TB也不过就10RMB左右。)
- 📄字库数据分2次,写入到W25Q64 SPI FLASH中。
/*字库写入*//*字库需要分2次写入FLASH,一次写1半,写完上半部分后,把if 1 改为 if 0,再写下半部分*//*CNFont.h也需要同步修改,写完注释掉这段代码*/ /*写完注释掉或者删除掉这段代码*/// #if 0
// W25Q64_WriteData(W25Q64_GBK_ADDR,(uint8_t *)Chinses_16,383041);
// printf("写字库上半部分 OK!\r\n");
// #elseW25Q64_WriteData(W25Q64_GBK_ADDR+383041,(uint8_t *)Chinses_16,383039);printf("写字库下半部分 OK!\r\n");
// #endif/*写完注释掉或者删除掉这段代码*/

- 👉通过MinPro-I编程器读取SPI FLASH ,写入的有效数据是767KB数据,到BB07F地址,对于存储16X16 Chinses_16字体,其实准备一颗1MB的 SPI FLASH 就足够了。

- 📘这里提供程序中的
Chinses_16字体库BIN文件,是从spi flash中提取出来的。如果自己有SPI flash编程器,可以直接烧录到SPI FLASH当中去。(经过验证,将裁剪后的bin文件烧录到4MB SPI FLASH中,挂载到mcu上,可以正确访问和读取数据。OLED显示正常).
链接:https://pan.baidu.com/s/13uU5Uc7yiiHDMtMMNd71ew?pwd=v0l7
提取码:v0l7
- 🌿8M spi flash 全部提取(未裁剪)原字库
链接:https://pan.baidu.com/s/1y8_p0PL-QeTQTkgahKGTXg?pwd=x324
提取码:x324
- W25QXX(针对WINBOND SPI FLASH)设备ID与容量关系

W25QXX Device ID
读取命令(0x90)
W25Q80的芯片ID为:0XEF13
W25Q16 的芯片ID为:0XEF14
W25Q32 的芯片ID为:0XEF15
W25Q64 的芯片ID为:0XEF16
W25Q128的芯片ID为:0XEF17
W25Q256的芯片ID为:0XEF18
W25Q512的芯片ID为:0XEF19
🌼OLED显示
- 🍁接线说明:
SPI FLASH ----- STM32F103VET6CS ---- PB12MOSI---- PB15MISO---- PB14SCK ---- PB13
----------------------------------OLED I2C SSD1306 --- STM32F103VET6SCL----- PB8SDA ---- PB9
- main.c:
/*
引脚接线说明SPI FLASH ----- STM32F103VET6CS ---- PB12MOSI---- PB15MISO---- PB14SCK ---- PB13
----------------------------------OLED I2C SSD1306 --- STM32F103VET6SCL----- PB8SDA ---- PB9*/#include "main.h"
#include "usart1.h"
#include "systick.h"
#include "oled_i2c.h"
#include "w25q64.h"
#include "cnfont.h"
#include "codetab.h"static void CLOCK_Config(void);
static void NVIC_Config(void);int main(void)
{CLOCK_Config(); //时钟配置NVIC_Config(); //中断优先级配置W25Q64_InitConfig();//初始化W25Q64USART1_Config();printf("WRITE Start, FLASH ID=%X\r\n",W25Q64_GetID());/*字库写入*//*字库需要分2次写入FLASH,一次写1半,写完上半部分后,把if 1 改为 if 0,再写下半部分*//*CNFont.h也需要同步修改,写完注释掉这段代码*//*写完注释掉或者删除掉这段代码*/// #if 1
// W25Q64_WriteData(W25Q64_GBK_ADDR,(uint8_t *)Chinses_16,383041);
// printf("写字库上半部分 OK!\r\n");
// #else
// W25Q64_WriteData(W25Q64_GBK_ADDR+383041,(uint8_t *)Chinses_16,383039);
// printf("写字库下半部分 OK!\r\n");
// #endif/*写完注释掉或者删除掉这段代码*/GPIO_ResetBits(GPIOB,GPIO_Pin_0);I2C_OLED_Cfg();OLED_Init();OLED_Fill(0xFF);//全屏点亮Delay_ms(50);OLED_Fill(0x00);//全屏灭Delay_ms(50);OLED_CLS();//清屏OLED_ShowStr(0, 0, (uint8_t *)"Loading now 1...", 2);Delay_ms(500);OLED_CLS();//清屏OLED_DrawBMP(0,0,128,8,LOGO_BMP);Delay_ms(2000);OLED_CLS();//清屏OLED_ShowChinese(0,0,"床前明月光,",16);OLED_ShowChinese(0,2,"疑是地上霜、",16);OLED_ShowChinese(0,4,"举头望明月?",16);OLED_ShowChinese(0,6,"疑是地上霜。",16);while(1){}
}
//外设时钟配置
static void CLOCK_Config(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);//1.配置GPIO GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_0);GPIO_SetBits(GPIOB,GPIO_Pin_1);
}//中断优先级初始化
static void NVIC_IRQPriority_Init(uint8_t IRQChannel,uint8_t PreemptionPriority, uint8_t SubPriority)
{NVIC_InitTypeDef NVIC_IRQ_Init;NVIC_IRQ_Init.NVIC_IRQChannel = IRQChannel;NVIC_IRQ_Init.NVIC_IRQChannelPreemptionPriority = PreemptionPriority;NVIC_IRQ_Init.NVIC_IRQChannelSubPriority = SubPriority;NVIC_IRQ_Init.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_IRQ_Init);
}
//配置中断优先级
static void NVIC_Config(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断优先级分组NVIC_IRQPriority_Init(USART1_IRQn,1,1);
}
📚工程源码
链接:https://pan.baidu.com/s/1SPauxXcXfs0JZvhfRF6zDw?pwd=hota
提取码:hota
相关文章:
STM32标准库驱动W25Q64模块读写字库数据+OLED0.96显示例程
STM32标准库驱动W25Q64 模块读写字库数据OLED0.96显示例程 🎬原创作者对W25Q64保存汉字字库演示: W25Q64保存汉字字库 🎞测试字体显示效果: 📑功能实现说明 利用W25Q64保存汉字字库,OLED显示汉字的时候&…...
【java】简单的Java语言控制台程序
一、用于文本文件处理的Java语言控制台程序示例 以下是一份简单的Java语言控制台程序示例,用于文本文件的处理。本例中我们将会创建一个程序,它会读取一个文本文件,显示其内容,并且对内容进行计数,然后将结果输出到控…...
【服务器数据恢复】HP EVA虚拟化磁盘阵列数据恢复原理方案
EVA存储结构&原理: EVA是虚拟化存储,在工作过程中,EVA存储中的数据会不断地迁移,再加上运行在EVA上的应用都比较繁重,磁盘负载高,很容易出现故障。EVA是通过大量磁盘的冗余空间和故障后rss冗余磁盘动态…...
08-OpenFeign-结合Sentinel,实现熔断降级
当我们在对服务远程调用时,会因为服务的请求超时、抛出异常等情况,导致调用失败。 如果短时间内,产生大量请求异常。引发上游的调用方请求积压,最终会引起整个调用链雪崩。 为此我们需要对核心的调用过程进行监控,当…...
15.实现数组的扁平化
实现方式1(递归) 普通的递归思路很容易理解,就是通过循环递归的方式,一项一项地去遍历,如果每一项还是一个数组,那么就继续往下遍历,利用递归程序的方法,来实现数组的每一项的连接: let arr […...
对话模型Demo解读(使用代码解读原理)
文章目录 前言一、数据加工二、模型搭建三、模型训练1、构建模型2、优化器与损失函数定义3、模型训练 四、模型推理五、所有Demo源码 前言 对话模型是一种人工智能技术,旨在使计算机能够像人类一样进行对话和交流。这种模型通常基于深度学习和自然语言处理技术&…...
Android 自定义BaseFragment
直接上代码: BaseFragment代码: package com.example.custom.fragment;import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx…...
[C#] 如何对列表,字典等进行排序?
对列表进行排序 下面是一个基于C#的列表排序的案例: using System; using System.Collections.Generic;class Program {static void Main(string[] args){// 创建一个列表List<int> numbers new List<int>() { 5, 2, 8, 1, 10 };// 使用Sort方法对列…...
Mac 下载安装Java、maven并配置环境变量
下载Java8 下载地址:https://www.oracle.com/java/technologies/downloads/ 根据操作系统选择版本 没有oracle账号需要注册、激活登录 mac直接选择.dmg文件进行下载,下载后安装。 默认安装路径:/Library/Java/JavaVirtualMachines/jdk-1…...
【多模态】27、Vary | 通过扩充图像词汇来提升多模态模型在细粒度感知任务(OCR等)上的效果
文章目录 一、背景二、方法2.1 生成 new vision vocabulary2.1.1 new vocabulary network2.1.2 Data engine in the generating phrase2.1.3 输入的格式 2.2 扩大 vision vocabulary2.2.1 Vary-base 的结构2.2.2 Data engine2.2.3 对话格式 三、效果3.1 数据集3.2 图像细粒度感…...
|Python新手小白低级教程|第二十章:函数(2)【包括石头剪刀布判断程序(模拟版)】
文章目录 前言一、复习一、函数实战之——if语句特殊系统1.判断等第分数(函数名为mark(参数num))2.石头剪刀布判断程序 二、练习总结 前言 Hello,大家好,我是你们的BoBo仔,感谢你们来阅读我的文…...
vue3 之 商城项目—home
home—整体结构搭建 根据上面五个模块建目录图如下: home/index.vue <script setup> import HomeCategory from ./components/HomeCategory.vue import HomeBanner from ./components/HomeBanner.vue import HomeNew from ./components/HomeNew.vue import…...
git flow与分支管理
git flow与分支管理 一、git flow是什么二、分支管理1、主分支Master2、开发分支Develop3、临时性分支功能分支预发布分支修补bug分支 三、分支管理最佳实践1、分支名义规划2、环境与分支3、分支图 四、git flow缺点 一、git flow是什么 Git 作为一个源码管理系统,…...
【Linux】学习-进程信号
进程信号 信号入门 生活角度的信号 你在网上买了很多件商品,再等待不同商品快递的到来。但即便快递没有到来,你也知道快递来临时,你该怎么处理快递。也就是你能“识别快递”,也就是你意识里是知道如果这时候快递员送来了你的包裹,你知道该如何处理这些包裹当快递员到了你…...
webgis后端安卓系统部署攻略
目录 前言 一、将后端项目编译ARM64 二、安卓手机安装termux 1.更换为国内源 2.安装ssh远程访问 3.安装文件远程访问 三、安装postgis数据库 1.安装数据库 2.数据库配置 3.数据导入 四、后端项目部署 五、自启动设置 总结 前言 因为之前一直做的H5APP开发…...
【数据分享】1929-2023年全球站点的逐日平均风速数据(Shp\Excel\免费获取)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 有关气象指标的监测站点数据,之前我们分享过1929-2023年全球气象站…...
【多模态大模型】视觉大模型SAM:如何使模型能够处理任意图像的分割任务?
SAM:如何使模型能够处理任意图像的分割任务? 核心思想起始问题: 如何使模型能够处理任意图像的分割任务?5why分析5so分析 总结子问题1: 如何编码输入图像以适应分割任务?子问题2: 如何处理各种形式的分割提示?子问题3:…...
Shell之sed
sed是什么 Linux sed 命令是利用脚本来处理文本文件。 可依照脚本的指令来处理、编辑文本文件。主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。 sed命令详解 语法 sed [-hnV][-e <script>][-f<script文件>][文本文件] sed [-nefr] [动作…...
AJAX——认识URL
1 什么是URL? 统一资源定位符(英语:Uniform Resource Locator,缩写:URL,或称统一资源定位器、定位地址、URL地址)俗称网页地址,简称网址,是因特网上标准的资源的地址&…...
《Docker极简教程》--Docker环境的搭建--在Linux上搭建Docker环境
更新系统:首先确保所有的包管理器都是最新的。对于基于Debian的系统(如Ubuntu),可以使用以下命令:sudo apt-get update sudo apt-get upgrade安装必要的依赖项:安装一些必要的工具,比如ca-certi…...
MCUXPresso for VS Code插件实战:从零构建NXP MCU的HelloWorld项目
1. 项目概述:为什么选择MCUXPresso for VS Code?如果你是一位嵌入式开发者,尤其是使用恩智浦(NXP)MCU的工程师,那么你大概率对MCUXpresso IDE不陌生。它是一个功能强大的集成开发环境,但有时我们…...
初次使用Taotoken从注册获取Key到完成第一次API调用的全流程指引
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 初次使用Taotoken从注册获取Key到完成第一次API调用的全流程指引 本文旨在为初次接触Taotoken平台的开发者提供一份清晰的入门指南…...
Electron应用上鸿蒙PC,安装包从180MB压到45MB,我做了哪些骚操作
Electron应用上鸿蒙PC,安装包从180MB压到45MB,我做了哪些骚操作 上个月老板丢给我一个任务:把现有的Electron应用搬到鸿蒙PC上。我花了两天把代码跑通了,build了一版安装包,一看体积——180MB。老板看了一眼࿰…...
SAP EWM实战:从产品到处理单位,两种库存转移操作保姆级教程
SAP EWM库存转移实战指南:产品与处理单位的精准操作 在仓库管理的日常工作中,库存转移是最基础却最容易出错的环节之一。特别是对于刚接触SAP EWM系统的管理员来说,面对不同形态的物料——散件产品和带包装的处理单位(HU),往往会产…...
magic-api异常处理与错误排查:常见问题解决方案大全
magic-api异常处理与错误排查:常见问题解决方案大全 【免费下载链接】magic-api magic-api 是一个接口快速开发框架,通过Web页面编写脚本以及配置,自动映射为HTTP接口,无需定义Controller、Service、Dao、Mapper、XML、VO等Java对…...
如何免费下载网页视频?VideoDownloadHelper浏览器插件终极指南
如何免费下载网页视频?VideoDownloadHelper浏览器插件终极指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 还在为无法保存网页…...
如何扛住十万级流量洪峰?扒开高并发架构的五层防御体系
在互联网的残酷战场上,流量既是黄金,也是洪水。试想这样一个场景:你们公司花重金请了一位顶流代言人,晚上 8 点准时开启一场“一元秒杀”活动。时间一到,原本平时只有几百 QPS(每秒请求数)的系统…...
Fluent模拟火箭发动机喷管?试试用分子动理论定义气体属性,避开数据缺失的坑
火箭发动机喷管仿真中的分子动理论实战:突破高温燃气物性数据困境 当你在Fluent中打开火箭发动机喷管的仿真项目时,面对H2/CO/H2O混合燃气在3000K温度梯度下的物性参数定义,是否曾为找不到可靠数据而抓狂?传统方法需要逐个温度点…...
IO杂记I
IO 杂记 一、Selector 与 select() selector.select() 不会创建新线程,而是让当前线程阻塞等待,直到有 I/O 事件就绪。 比喻:一个人站在门口,不来客人就不动。selector.selectNow() 是非阻塞版本:瞥一眼门口࿰…...
别再死记硬背了!用Cisco Packet Tracer搞定IPv6地址配置(附EUI-64和静态路由实战)
思科模拟器实战:从零掌握IPv6地址配置与路由技术 在数字化浪潮席卷全球的今天,IPv6作为下一代互联网协议,正逐步取代IPv4成为网络世界的基石。然而,对于许多网络初学者来说,IPv6那长达128位的地址和全新的配置方式往往…...
