一 、概述
目前,越来越多的应用需要扩展外部的Flash来满足存储需求,在调试及批量生产的过程中,需要对外扩的Flash进行烧录操作。在之前的学习中,一直用外部SPI Flash存放字库文件,之前的数据下载方法是用SD卡拷贝到SPIFLASH中,一直觉得在开发板上学习还算方便,如果在项目中应用,不是很方便,偶然机会,发现ST官方工具STM32 ST-LINK Utility支持对外部SPIFLASH直接进行读写。前几天介绍了在原子精英板上,用STM32 ST-LINK实现中文字库、图片下载的方法。
本文中介绍基于STM32F4系列的外挂SpiFlash烧录方法。
二、硬件平台
原子阿波罗开发板(SPIFLASH芯片信号W25Q128),单片机STM32F429。
三、代码解析
工程创建
该工程比较特殊,无main函数,其中system_stm32f4xx.c和大家熟悉的工程文件相同,BSP_sFLASH.c文件为外挂Flash的驱动程序,主要完成外挂Flash的初始化、读、写、擦除等操作。针对不同的Flash型号完成Loader文件夹下Dev_Info.c和Loader_Src.c文件编写。
DevInfo.c文件
Dev_Info.c中声明了结构体StorageInfo,包含ST-LINK Utility编程及擦除芯片的信息。代码如下:
/*
* W25Q256
* 4Kbytes为1个Sector
* 16个扇区为1个Block
* 容量为32M字节
*/
struct StorageInfo const StorageInfo = {
"W25Q256_REG", // FLASH 名称
SPI_FLASH, // FLASH类型
0x00000000, // FLASH 起始地址
0x02000000, // FLASH 大小,单位字节
256, // page大小
0xFF, // 擦除FLASH后,FLASH中的默认数据
// Specify Size and Address of Sectors (view example below)
4096, 0, // Sector大小: 4KBytes
SECTOR_END // SECTOR_END
};
Loader_Src.c文件
提供ST-LINKUtility的External Loader功能所需要的函数,主要代码如下:
首先需完成STM32时钟初始化,外挂Flash初始化。
int Init (void)
{
SystemInit(); //初始化时钟
Stm32_Clock_Init(360,25,2,8);//设置时钟,180Mhz
sFLASH_Init(); //初始化sFLASH,如W25Q128等
return 1;
}
按如下格式声明外挂Flash的读函数。
int Read (uint32_t Address, uint32_t Size, uint8_t* buffer)
{
sFLASH_ReadBuffer(buffer, Address, Size);
return 1;
}
按如下格式声明外挂Flash的写函数。
int Write (uint32_t Address, uint32_t Size, uint8_t* buffer)
{
sFLASH_WriteBuffer(buffer, Address, Size);
return 1;
}
按如下格式声明外挂Flash的芯片擦除函数。
int MassErase (void)
{
sFLASH_EraseBulk();
return 1;
}
按如下格式声明外挂Flash的扇区擦除函数。
int SectorErase (uint32_t EraseStartAddress ,uint32_t EraseEndAddress)
{
EraseStartAddress = EraseStartAddress - EraseStartAddress%0x10000;
while (EraseEndAddress>=EraseStartAddress)
{
sFLASH_EraseSector(EraseStartAddress);
EraseStartAddress += 0x10000;
}
return 1;
}
编写校验函数如下:
uint32_t CheckSum(uint32_t StartAddress, uint32_t Size, uint32_t InitVal)
{
uint8_t missalignementAddress = StartAddress%4;
uint8_t missalignementSize = Size ;
int cnt;
uint32_t Val;
uint8_t value;
StartAddress-=StartAddress%4;
Size += (Size%4==0)?0:4-(Size%4);
for(cnt=0; cnt>8 & 0xff);
InitVal += (uint8_t) (Val>>16 & 0xff);
InitVal += (uint8_t) (Val>>24 & 0xff);
missalignementAddress-=1;
break;
case 2:
InitVal += (uint8_t) (Val>>16 & 0xff);
InitVal += (uint8_t) (Val>>24 & 0xff);
missalignementAddress-=2;
break;
case 3:
InitVal += (uint8_t) (Val>>24 & 0xff);
missalignementAddress-=3;
break;
}
}
else if((Size-missalignementSize)%4 && (Size-cnt) <=4)
{
switch (Size-missalignementSize)
{
case 1:
InitVal += (uint8_t) Val;
InitVal += (uint8_t) (Val>>8 & 0xff);
InitVal += (uint8_t) (Val>>16 & 0xff);
missalignementSize-=1;
break;
case 2:
InitVal += (uint8_t) Val;
InitVal += (uint8_t) (Val>>8 & 0xff);
missalignementSize-=2;
break;
case 3:
InitVal += (uint8_t) Val;
missalignementSize-=3;
break;
}
}
else
{
InitVal += (uint8_t) Val;
InitVal += (uint8_t) (Val>>8 & 0xff);
InitVal += (uint8_t) (Val>>16 & 0xff);
InitVal += (uint8_t) (Val>>24 & 0xff);
}
StartAddress+=4;
}
return (InitVal);
}
更新函数如下:
int Verify (uint32_t MemoryAddr, uint32_t RAMBufferAddr, uint32_t Size)
{
uint32_t VerifiedData = 0;
uint8_t TmpBuffer = 0x00;
Size*=4;
while (Size>VerifiedData)
{
sFLASH_ReadBuffer(&TmpBuffer, MemoryAddr+VerifiedData, 1);
if (TmpBuffer != *((uint8_t*)RAMBufferAddr+VerifiedData))
return MemoryAddr+VerifiedData;
VerifiedData++;
}
return 0;
}
生成文件
在user中的Run#1中输入cmd.exe /C copy "!L""..\..\..\@L.stldr",如下图,编译后生成一个.stldr的文件。将该文件拷贝到:STM32 ST-LINK Utility v4.2.0 setup.exe安装目录\STM32ST-LINK Utility\ST-LINK Utility\ExternalLoader文件夹下。
四、效果展示
打开软件STM32 ST-LINK Utility->External Loader->Add ExteranlLoader->勾选相应文件(如图)->Validate
擦除外部FLASH。ExternalLoader->W25Q256_REG->Mass Erase。
下载字库、图片或其他文件到外部FLASH
等待下载结束,耗时约2分钟,显示Verification…OK,下载成功。
五、代码下载
代码地址:一种基于STM32F4的字库及图片下载工程源码
打字不易,点波关注,评论区留下邮箱,作者无偿提供源码和问题解答。