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");
//	#else
		W25Q64_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    -----   STM32F103VET6
	CS  ---- PB12
	MOSI---- PB15
	MISO---- PB14
	 SCK ---- PB13
----------------------------------
	OLED I2C SSD1306  ---     STM32F103VET6
		SCL-----  PB8
		SDA ----  PB9
  • main.c:
/*
引脚接线说明

SPI FLASH    -----   STM32F103VET6
	CS  ---- PB12
	MOSI---- PB15
	MISO---- PB14
	 SCK ---- PB13
----------------------------------
	OLED I2C SSD1306  ---     STM32F103VET6
		SCL-----  PB8
		SDA ----  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();//初始化W25Q64
	USART1_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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SVD奇异值分解

一、奇异值 奇异值(Singular Values)是线性代数中矩阵的重要性质之一,与奇异值分解(SVD)密切相关。让我们来更详细地了解一下奇异值的概念: 定义: 对于一个矩阵 ( A ),它的奇异值是…

【Chrono Engine学习总结】4-vehicle-4.1-vehicle的基本概念

由于Chrono的官方教程在一些细节方面解释的并不清楚,自己做了一些尝试,做学习总结。 1、基本介绍 Vehicle Overview Vehicle Mannel Vehicle的官方demo 1.1 Vehicle的构型 一个车辆由许多子系统构成:悬挂、转向、轮子/履带、刹车/油门、动…

双场板功率GaN HEMT电容模型以精确模拟开关行为

标题:Capacitance Modeling in Dual Field-Plate Power GaN HEMT for Accurate Switching Behavior(TED.16年) 摘要 本文提出了一种基于表面电位的紧凑模型,用于模拟具有栅极和源极场板(FP)结构的AlGaN/G…

JMM(Java内存模型)

Java内存模型(Java Memory Model,简称JMM)是Java语言规范中定义的一个抽象概念,它描述了程序中各个变量(包括实例字段、静态字段和构成数组对象的元素)在并发环境下的访问规则和一致性保证。JMM的主要目标是…

python+flask+django医院预约挂号病历分时段管理系统snsj0

技术栈 后端:python 前端:vue.jselementui 框架:django/flask Python版本:python3.7 数据库:mysql5.7 数据库工具:Navicat 开发软件:PyCharm . 第一,研究分析python技术&#xff0c…

点云标注工具

目录 3d手势识别 c 3d关键点,Bounding Box Labels Rectangle Labels KITTI 3D Ground Truth Annotator c标注工具 3d手势识别 GitHub - 99xtaewoo/Automated-Hand-3D-pose-annotation-Tool: Automated Hand 3D pose annotation Tool c 3d关键点,Bou…

【Django】Django文件上传

文件上传 1 定义&场景 定义&#xff1a;用户可以通过浏览器将图片等文件上传至网站。 场景&#xff1a; 用户上传头像。 上传流程性的文档[pdf&#xff0c;txt等] 2 上传规范-前端[html] 文件上传必须为POST提交方式 表单 <form> 中文件上传时必须带有 enctype…

电视上如何下载软件

电视上如何下载软件&#xff0c;告诉大家一个简单的方法&#xff0c;可以用DT浏览器下载软件&#xff0c;然后会自动安装这个软件&#xff0c;如有技术问题&#xff0c;可以免费解答

【初中生讲机器学习】8. KNN 算法原理 实践一篇讲清!

创建时间&#xff1a;2024-02-11 最后编辑时间&#xff1a;2024-02-12 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名初三学生&#xff0c;热爱计算机和数学&#xff0c;我们一起加…

从零开始学howtoheap:fastbins的house_of_spirit攻击3

how2heap是由shellphish团队制作的堆利用教程&#xff0c;介绍了多种堆利用技术&#xff0c;后续系列实验我们就通过这个教程来学习。环境可参见从零开始配置pwn环境&#xff1a;从零开始配置pwn环境&#xff1a;从零开始配置pwn环境&#xff1a;优化pwn虚拟机配置支持libc等指…

Python:解析获取连续的重叠对pairwise

简介&#xff1a;pairwise函数&#xff0c;返回从输入迭代器获取的重叠对的迭代器&#xff0c;是Python 3.10 新特性&#xff0c;表示一个迭代器从对象中获取连续的重叠对&#xff0c;在某些场景中可以优化代码运行效率。pairwise 函数是一种用于处理列表中元素之间配对操作的通…

渗透专用虚拟机(公开版)

0x01 工具介绍 okfafu渗透虚拟机公开版。解压密码&#xff1a;Mrl64Miku&#xff0c;压缩包大小&#xff1a;15.5G&#xff0c;解压后大小&#xff1a;16.5G。安装的软件已分类并在桌面中体现&#xff0c;也可以使用everything进行查找。包含一些常用的渗透工具以及一些基本工…

腾讯云4核8G服务器多少钱?2024精准报价

腾讯云4核8G服务器S5和轻量应用服务器优惠价格表&#xff0c;轻量应用服务器和CVM云服务器均有活动&#xff0c;云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元&#xff0c;5年6490.44元&#xff0c;标准型SA2服务器1444.8元一年&#xff0c;轻量应用服务器4核8G12M带宽一…

app逆向-android-studio安装使用教程

Android Studio 是谷歌推出的一个Android集成开发工具&#xff0c;基于IntelliJ IDEA. 类似 Eclipse ADT&#xff0c;Android Studio 提供了集成的 Android 开发工具用于开发和调试。 android-studio下载地址&#xff1a;https://developer.android.com/studio/archive androi…

【ES】--ES集成自定义分词库

目录 一、相关安装1、(window单机)elasticsearch安装2、安装Elasticvue插件3、ik分词器插件4、ES集成自定义词库 一、相关安装 1、(window单机)elasticsearch安装 Win10下下载ES组件&#xff0c;安装部署如下&#xff1a;JDK1.8、elasticsearch-7.3.2-windows-x86_64。 Elast…

【前端web入门第六天】01 CSS浮动

⭐️第六天目标 解决布局问题如多个div标签在同一行的问题 简单来说,就是可以两个标签,一个在左边,另一个在右边. &#x1f449;相关知识 标准流浮动flex布局❗️ ❗️ ❗️ 标准流是先导,浮动和flex布局都可以解决问题,但是浮动在目标开发领域较为落后,主流的解决办法是flex…

Linux第51步_移植ST公司的linux内核第3步_添加修改设备树

1、设备树文件的路径 1)、创建linux中的设备树头文件 在“my_linux/linux-5.4.31/arch/arm/boot/dts/”目录中&#xff0c;以“stm32mp15xx-edx.dtsi”为蓝本&#xff0c;复制一份&#xff0c;并命名为 “stm32mp157d-atk.dtsi”&#xff0c;这就是我们开发板的设备树头文件。…

车载诊断协议DoIP系列 —— 协议中术语解释和定义

车载诊断协议DoIP系列 —— 协议中术语解释和定义 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,…

Python常用模块

前言 在使用Python进行开发时&#xff0c;会经常使用到不同的模块来帮助我们完成某部分功能的实现&#xff0c;因此掌握一些常用模块的常用方式可以帮助我们加速程序开发。 time模块 在Python中通常有以下几种方式来表示时间: 1.时间戳(timestamp),表示的是从1970年1月1日0…

使用Docker快速部署MySQL

部署MySQL 使用Docker安装&#xff0c;仅仅需要一步即可&#xff0c;在命令行输入下面的命令 docker run -d \--name mysql \-p 3306:3306 \-e TZAsia/Shanghai \-e MYSQL_ROOT_PASSWORD123456 \mysql MySQL安装完毕&#xff01;通过任意客户端工具即可连接到MySQL. 当我们执…