STM32 STD/HAL库驱动W25Q64模块读写字库数据+OLED0.96显示例程

STM32 STD/HAL库驱动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

🔨字库文件(.BIN)制作

  • 🌿通过C代码将字库数组转换成.bin文件。(将下面的代码拷贝下来,通过VSCode软件创建.c文件将字库数组添加进来,然后运行,将自动生成.BIN文件。)(依赖插件c\C插件、Code Runner)
const unsigned char Chinses_16[766080]={........};//字库数组
int main() {size_t size = sizeof(Chinses_16[0]);size_t count = sizeof(Chinses_16) / size;FILE *fp = fopen("output.bin", "wb");if (fp == NULL) {printf("Failed to open file.\n");return 1;}size_t elements_written = fwrite(Chinses_16, size, count, fp);if (elements_written != count) {printf("Failed to write data to file.\n");fclose(fp);return 1;}fclose(fp);printf("Data written successfully.\n");return 0;
}

在这里插入图片描述
在这里插入图片描述

  • 🌿由上面代码自动生成的字体文件:(经烧录测试,显示没有问题)
链接:https://pan.baidu.com/s/1oqJ5WeaJKv6LI-p-LUPojA?pwd=0vfh 
提取码:0vfh
  • 🌿将生成的.bin文件通过SPI FLASH 编程器烧录到SPI FLASH(W25QXX)芯片中即可。
  • 🔑或者参考《将数组文件转换成bin格式文件》制作。测试过,此方法生成BIN文件时,会报非法字符情况,烧录后读取存在乱码的情况。

🌼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

📘基于HAL库驱动(不包含字库文件)

  • 🔖采用标准I2C模式+SPI模式
链接:https://pan.baidu.com/s/1sfs3LxUnYwfvZ8iVMaFeHQ?pwd=onky 
提取码:onky
  • 🔖采用快速I2C模式+SPI DMA模式:
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

链接:https://pan.baidu.com/s/11Y9boVofu7Og9CnbV1_6oQ?pwd=quun 
提取码:quun

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/680518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

寒假作业——2/13

作业1 作业2 cp cp 当前的文件位置 复制到哪个位置 格式 : cp 路径/文件 路径/目录名/重新命名的目录名 mv mv 当前的文件位置 复制到哪个位置 格式 : mv 路径/文件 路径/目录名/重新命名的目录名 也可进行重命名操作 find 查找文件 find 目标路径 -name 文件名 后续…

leetcode(数组)128.最长连续序列(c++详细解释)DAY8

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 示例 1&a…

政安晨:在Jupyter中【示例演绎】Matplotlib的官方指南(二){Image tutorial}·{Python语言}

咱们接着上一篇,这次咱们讲使用Matplotlib绘制图像的简短尝试。 我的这个系列的上一篇文章在这里: 政安晨:在Jupyter中【示例演绎】Matplotlib的官方指南(一){Pyplot tutorial}https://blog.csdn.net/snowdenkeke/ar…

IM聊天系统为什么需要做消息幂等?如何使用Redis以及Lua脚本做消息幂等【第12期】

0前言 消息收发模型 第一张图是一个时序图,第二张图是一个标清楚步骤的流程图,更加清晰。消息的插入环节主要在2步。save部分。主要也是对这个部分就行消息幂等的操作。 前情提要:使用Redis发布 token 以及lua脚本来共同完成消息的幂等 目…

119.乐理基础-五线谱-五线谱的标记

内容参考于:三分钟音乐社 上一个内容:音值组合法(二) 力度记号:简谱里什么意思,五线谱也完全是什么意思,p越多就越弱,f越多就越强,然后这些渐强、渐弱、sf、fp这些标记…

Proteus -模拟串口被关闭后怎样打开

Proteus -模拟串口被关闭后怎样打开 点击恢复弹出窗口,即可重新打开

WPF中值转换器的使用

什么是值转换器 在WPF(Windows Presentation Foundation)中,值转换器(Value Converter)是一种机制,允许你在绑定时转换绑定源和绑定目标之间的值。值转换器实现了 IValueConverter 接口,该接口…

【华为 ICT HCIA eNSP 习题汇总】——题目集12

1、企业网络内部常常采用私有 IP 地址进行通信,以下哪个地址属于私有 IP 地址? A、0.1.1.1 B、127.5.4.3 C、128.0.0.5 D、172.24.35.36 考点:网络层 解析:(D) A类 IP 地址中,10.0.0.0 ~ 10.255…

深入学习《大学计算机》系列之第1章 1.7节——图灵机的一个例子

一.欢迎来到我的酒馆 第1章 1.7节,图灵机的一个例子。 目录 一.欢迎来到我的酒馆二.图灵机2.1 艾伦-图灵简介2.2 图灵机简介 三.图灵机工作原理3.1 使用图灵机打印二进制数3.2 图灵机工作原理总结 四.总结 二.图灵机 本节内容主要介绍计算机科学之父——艾伦-图灵、…

Java学习-常用API-新增时间

1.学习JDK8新增时间的原因? 2.JDK8新增了那些时间? 代替calendar的 localDate localTime localDateTime 常用APi及代码示例: ZoneIdZonedDateTime 常用方法 代码示例: 代替Date的 Instant常见方法及其代码示例: 注…

权限提升:利用Linux漏洞提权

目录 Linux权限基础 Linux用户权限 Linux文件权限 特殊的Linux文件权限 Linux本机信息收集 利用Linux漏洞进行提权 脏牛漏洞 pkexec Linux权限基础 Linux用户权限 在Linux中,根据权限的不同,大致可以分为三种:超级用户(…

C#,卢卡斯数(Lucas Number)的算法与源代码

1 卢卡斯数(Lucas Number) 卢卡斯数(Lucas Number)是一个以数学家爱德华卢卡斯(Edward Lucas)命名的整数序列。爱德华卢卡斯既研究了这个数列,也研究了有密切关系的斐波那契数(两个…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月13日,星期二

每天一分钟,知晓天下事! 2024年2月13日 星期二 农历正月初四 1、 春节假期旅游爆火!多地景区宣布门票售罄,建议错峰错区游览。 2、 中国旅游研究院:预计2024年全年国内旅游人数将超过60亿人次。 3、 应急管理部&#…

Solidworks:从2D走向3D

Sokidworks 的强大之处在于三维实体建模,这个形状看似复杂,实际上只需要拉伸一次,再做一次减法拉伸就行了。第一次做三维模型,费了不少时间才搞明白。 接下来做一个稍微复杂一点的模型,和上面这个操作差不多&#xff0…

基于Seaborn和Matplotlib的可视化案例分析

处理数据有时会有点无聊。将原始数据转换为可理解的格式是整个过程中最重要的部分之一,那么为什么只停留在数字上,当我们可以将数据可视化为令人兴奋的图表时,这些图表可以在python中获取。这篇文章将重点探索耐人寻味的预处理之旅。 Seabor…

SSM+SpringBoot框架

单例bean是线程安全的吗 AOP Spring事务失效 第四种,在方法内部使用,需要用代理类调用此方法 bean生命周期 bean的循环依赖 SpringMVC执行流程 、 SpringBoot自动配置原理 Spring常见注解 MyBatis执行流程 MyBatis延迟加载 MyBatis缓存

最新在线看4K高清电影网站推荐

随着互联网技术的发展,观看高清电影已经不再是难事。这里我为大家分享几个最新的在线看4K高清电影网站,让您在家就能享受到极致观影体验。 通过下面这个即可 1. 【超清影视】 【超清影视】是国内新兴的4K高清电影网站,拥有海量的影片资源&a…

000——对i.MAX6uLL进行开箱检查

目录 00外观检查 01有线网卡检查 02USB-host测试 03耳机测试 04按键测试 05查看CPU温度 00外观检查 看起来没什么问题,买了半年了刚开始要做 01有线网卡检查 开机启动正常,韦东山老师还写了个欢迎界面,这个我后面因为要用于毕业设计&am…

《Linux 简易速速上手小册》第5章: 用户与群组管理(2024 最新版)

文章目录 5.1 管理用户账户5.1.1 重点基础知识5.1.2 重点案例:创建一个新的开发者账户5.1.3 拓展案例 1:禁用用户登录5.1.4 拓展案例 2:设置账户到期 5.2 群组概念与管理5.2.1 重点基础知识5.2.2 重点案例:为项目团队设置群组5.2.…

《Linux 简易速速上手小册》第3章: 文件系统与权限(2024 最新版)

文章目录 3.1 Linux 文件系统结构3.1.1 重点基础知识3.1.2 重点案例:设置一个 Web 服务器3.1.3 拓展案例 1:日志文件分析3.1.3 拓展案例 2:备份用户数据 3.2 理解文件权限3.2.1 重点基础知识3.2.2 重点案例:共享项目文件夹3.2.3 拓…