中国做机床的公司网站,知乎推广和引流技巧,企业网站建设前期准备,在家开个代加工厂STM32 STD/HAL库驱动W25Q64 模块读写字库数据OLED0.96显示例程 #x1f3ac;原创作者对W25Q64保存汉字字库演示#xff1a; W25Q64保存汉字字库 #x1f39e;测试字体显示效果#xff1a;
#x1f4d1;功能实现说明 利用W25Q64保存汉字字库#xff0c;OLED显示汉字的时… 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_ADDR383041,(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?pwdv0l7
提取码v0l78M spi flash 全部提取未裁剪原字库
链接https://pan.baidu.com/s/1y8_p0PL-QeTQTkgahKGTXg?pwdx324
提取码x324W25QXX针对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?pwd0vfh
提取码0vfh将生成的.bin文件通过SPI FLASH 编程器烧录到SPI FLASHW25QXX芯片中即可。或者参考《将数组文件转换成bin格式文件》制作。测试过此方法生成BIN文件时会报非法字符情况烧录后读取存在乱码的情况。
OLED显示
接线说明
SPI FLASH ----- STM32F103VET6CS ---- PB12MOSI---- PB15MISO---- PB14SCK ---- PB13
----------------------------------OLED I2C SSD1306 --- STM32F103VET6SCL----- PB8SDA ---- PB9main.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.hstatic 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_ADDR383041,(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?pwdhota
提取码hota基于HAL库驱动不包含字库文件
采用标准I2C模式SPI模式
链接https://pan.baidu.com/s/1sfs3LxUnYwfvZ8iVMaFeHQ?pwdonky
提取码onky采用快速I2C模式SPI DMA模式 链接https://pan.baidu.com/s/11Y9boVofu7Og9CnbV1_6oQ?pwdquun
提取码quun