W25Q64:通过上位机向W25Q64任意地址写入字库文件

结果

烧录上位机
STM32F103RC从W25Q64中读取中文字库

思路

整体思路

从上位机软件获取文件大小,起始地址,然后以每帧1024byte * 4,通过STM32,向FLASH中写入该文件
协议:帧头 + 数据长度 + 命令码 + 数据 + ACC16;
大概步骤

说明

做一个项目需要用到flash中的中文字库,看了一下野火的教程,发现要从SD卡中将字库文件写入W25Q64中,网上找了一下,没找到合适的;于是就自己动手修改了以前写的一个上位机(VS C#),配合STM32将需要发送的文件以每帧1024byte进行发送,为确保数据完整,每帧数据都要经过校验

步骤

1.上位机以50ms间隔向STM32发送准备开始命令

上位机:AA55000C2F01000000000003FE42017F

                send_downcmd[0] = 0xAA;
                send_downcmd[1] = 0x55;
                send_downcmd[2] = 0x00;
                send_downcmd[3] = 0x0C;
                send_downcmd[4] = 0x2F;
                send_downcmd[5] = 0x01;
                send_downcmd[6] = start_addr_flash[0]; //起始地址
                send_downcmd[7] = start_addr_flash[1];
                send_downcmd[8] = start_addr_flash[2];
                send_downcmd[9] = start_addr_flash[3];

                send_downcmd[10] = (byte)(iBinFileLen >> 24); //文件大小
                send_downcmd[11] = (byte)(iBinFileLen >> 16);
                send_downcmd[12] = (byte)(iBinFileLen >> 8);
                send_downcmd[13] = (byte)iBinFileLen;



                for (int i = 2; i < 14; i++) //ACC计算
                {
                    sum[0] += send_downcmd[i];
                }
                send_downcmd[14] = (byte)(sum[0] >> 8);
                send_downcmd[15] = (byte)(sum[0]);

                serialPort1.Write(send_downcmd, 0, 16);  //首次发送 
                textBox1.AppendText(byteToHexStr(send_downcmd, 16)); //AA 55 00 08 2F 01 81 56 01 08 01 18
                textBox1.AppendText(" 等待应答......\r\n");

                System.Threading.Thread.Sleep(50); //延时25ms

2.STM32应答,并开始擦除相应扇区

下位机:AA550003F200F5

	Ack_data2(); //第一次应答
							//获取起始地址
							write_addr  = rx_data->head[6] << 24 | rx_data->head[7] <<16 | rx_data->head[8] << 8 | rx_data->head[9];
							//获取文件大小
							file_size =  rx_data->head[10] << 24 | rx_data->head[11] <<16 | rx_data->head[12] << 8 | rx_data->head[13];
							sector_num = file_size / 4096;
							if(file_size % 4096)sector_num += 1;
							for(j=0;j < sector_num ;j++)//擦除扇区,起始位置710*4096共2116KB
							{
								SPI_FLASH_SectorErase(j*4096);
							}

3.上位机停止向STM32发送开始命令,并等待擦除完成

在串口接收事件中: timer1.Stop();//停止定时器

4.FLASH擦除完成,并向上位机发送开始写FLASH命令

下位机:AA550003F000F3
Ack_data(); //擦除完成应答

5.上位机向STM32发送第一帧数据

        serialPort1.Write(send_downdata, 0, 11);  //发送头  
        serialPort1.Write(aBinFileBuf, updData_T.sendcnt * 1024, 1024);  //发送 1K   
        serialPort1.Write(send_downdacc, 0, 2);  //发送校验

6.STM32收到数据后,放到缓冲区准备写入FLASH

	下位机:AA550003F000F3  //应答获取到正确帧
	
	(为什么不直接发4096byte:因为上位机是以前写来烧录BootLoader固件用的,帧大小是1024byte,所以就懒得改了)

7.STM32以扇区为单位向FLASH中写入剩下的数据

		最后一帧如果不够1024byte,则对1024求余
							if((len - 9) < 1024)
							{
								if(w25q64_n == 1)
								{
									SPI_FLASH_BufferWrite(uasrt_rev_buff, write_addr, (len - 9)); //最后一帧
								}
								else if(w25q64_n > 1)
								{
									SPI_FLASH_BufferWrite(uasrt_rev_buff, write_addr, (w25q64_n * 1024) + (len - 9)); //最后n帧
								}
							}
							else if(w25q64_n >= 4) 
							{
								w25q64_n = 0;
								SPI_FLASH_BufferWrite(uasrt_rev_buff, write_addr, 4096);//写FLASH
								write_addr+=4096;	
							}
							Ack_data(); //应答写入成功

链接:https://pan.baidu.com/s/1jZChgEG5K1beyP-f2zjdRw
提取码:2828
–来自百度网盘超级会员V6的分享

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
w25x16 SPI FLASH读写 串口监测输出STC8A8K单片机KEIL工程文件源码 FLASH w25x16 2M外部flash测试 W25X16芯片,就是16Mbit 一byte等于8bit 也就是2M字节的存储空间。 256bytes为一页 4Kbytes为一个Sector (扇区) 16个扇区为1个Block (块) W25X16 容量为2M字节,共有32个Block,512个Sector 而且W25X16最小擦除量是一个扇区 即4k字节空间 W25X16擦写周期多达 10W次,具有 20年的数据保存期限, 支持电压为 2.7~3.6V ,最大SPI 时钟可以到80Mhz。 程序上是将一个字符串存到了flash地址100开始的位置,然后去读取存入的数据到数组中,在将读到的 数组数据其显示出来 整个过程由串口检测 主频为11.0592MHz 串口波特率为9600 */ #include "stc8.h" //STC15头文件 #include "def.h" //宏定义 常用函数 #include "delay.h" //延时函数 #include "spi.h" #include "flash.h" #include "uart.h" u8 scan[]={"STC8 FLASH test"}; //测试字符串 u8 buffer[19]; //接收数组 void main() { SP=0X80; //调整堆栈指向 手册286页 详解 Init_SPI(); //SPI初始化 UartInit(); //串口初始化 if(SPI_Flash_ReadID()==0xef14) UartSendStr("外部FLASH初始化成功!\r\n"); else { UartSendStr("外部FLASH初始化失败!\r\n"); while(1); } SPI_Flash_Erase_Sector(0); //擦除地址为0扇区 4k字节 SPI_Flash_Write_NoCheck(scan,100,15); //在地址100位置写入字符串 SPI_Flash_Read(buffer,100,16); //在地址100位置处读取字符串并存入buffer数组中 UartSendStr("地址100数据:\r\n"); UartSend(buffer,15); while(1); }
根据提供的引用内容,W25Q64是一种FLASH存储类型的芯片。你提供的代码是用于初始化和读取W25Q64芯片的。根据引用\[1\]中提供的链接,你可以下载完整的工程代码来使用。根据引用\[2\]中的代码,你可以看到W25Q64的引脚定义和一些API函数的声明。其中,W25q64_ReadID函数用于读取W25Q64的ID。根据引用\[3\]中的代码,该函数通过发送特定的命令和数据来读取ID,并将结果打印出来。如果你在下载字库时遇到问题,可能是由于其他原因引起的,你可以检查你的代码和硬件连接是否正确,或者参考W25Q64的参考手册来查找解决方法。 #### 引用[.reference_title] - *1* [STM32入门开发: 介绍SPI总线、读写W25Q64(FLASH)(硬件+模拟时序)](https://blog.csdn.net/xiaolong1126626497/article/details/117648539)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [基于STM32F401RET6字库烧录(SPI&W25Q64驱动)](https://blog.csdn.net/hedada833/article/details/126036058)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值