通过上位机向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的分享