常见的SPI Flash:W25Qxx系列,本文以W25Q16为实例制作Keil下载算法。
如下图,红框内的东西就是下载算法。
只要导入下载算法后,就可以在烧录MCU的同时对W25Q16页进行烧录。此操作可方便LCD运用场景,字库、图片存放在外部Flash的烧录。
实际操作:
1、硬件:STM32G030C8T6、W25Q16(2MB FLASH)
2、算法对应的硬件连接图:
3、工程搭建:
①进入keil安装目录下的 \ARM\Pack\ARM\CMSIS\version\Device 路径(vesion为实际安装的keil pack的版本号),将 _Template_Flash 文件夹拷贝出来,以此为工程模板。
②用keil打开工程,点击“魔术棒”,Target页面下,编译器版本要选择V5.xx的。
Device页面,选择对应的单片机型号。
Ouput页面,设置生成文件的名称。
User页面,设置如下:
cmd.exe /C copy "Flash_Algx\%L" ".\@L.FLM"
cmd.exe /C copy ".\@L.FLM" "C:\Keil_v5\ARM\Flash\@L.FLM"
(C:\Keil_v5 为Keil的安装路径,ARM\Flash为路径下的下载算法存放地址)
C/C++页面,设置如下。
ASM页面,设置如下。
Linker页面,设置如下。
点击中间那个红框中的“Edit”,
打开后的文件内容为(如果与下面的代码不符,则手动修改):
; Linker Control File (scatter-loading)
;
PRG 0 PI ; Programming Functions
{
PrgCode +0 ; Code
{
* (+RO)
}
PrgData +0 ; Data
{
* (+RW,+ZI)
}
}
DSCR +0 ; Device Description
{
DevDscr +0
{
FlashDev.o
}
}
③以上设置完成后,开始生成工程。
点击下图红框内的按钮。
打开后,从上到下点击对应的框。
点击“STM32Cube HAL”后面按钮后,
跳出STM32Cube页面,开始配置MCU
配置完IO口和时钟频率之后(注意时钟频率会影响SPI的通讯速率),配置结束之后,点击项目设置,只需要设置如下选项即可,
设置完成后直接点击生成代码。
生成代码之后,用keil打开项目工程后会多出以下两个代码集,
此时,需要左击“Device”,如下图,点击红框中设置,
进入设置后,如下图,从上到下依次点击红框中的信息,
当点击确定之后,会发现STM32Cube生成的system_stm32g0xx.c不能用了。
此时需要自己从别的项目工程中拷贝一份system_stm32g0xx.c放到本工程中,同时在工程文件中添加,此时顺便将W25Qxx.c(FLASH驱动代码)和system_stm32g0xx.c一起添加进来,如下图。
④开始修改代码
点击main.c
先在main.c中重定义如下代码。
之后将“int main(void)”改为“int Init_main(void)”,同时对原本“int main(void)”中的函数做出修改,如下图
之后开始修改FlashDev.c,如下图所示文件,
做出如下修改,
注意超时时间要合理,全片擦除可能在10-20s左右。
之后开始修改FlashPrg.c,代码如下,
由于在FlashDev.c定义了地址为0x90000000所以先设置一个基础地址宏:
#define SPI_FLASH_MEM_ADDR 0x90000000
初始化函数:
extern int Init_main(void);
int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
/* Add your Code */
Init_main();
if(BSP_W25qxx_ReadID() != W25Q16)
{
//return (1);
}
return (0); // Finished without Errors
}
注意:在FlashPrg.c中的函数都有返回值,同时返回0表示正常,返回1表示异常。
清除初始化函数不修改:
int UnInit (unsigned long fnc) {
/* Add your Code */
return (0); // Finished without Errors
}
全片擦除函数:
int EraseChip (void) {
/* Add your Code */
for(uint16_t i = 0; i < 512; i++)
{
BSP_W25qxx_Erase_Sector(i * 0x1000);
}
return (0); // Finished without Errors
}
扇区擦除函数:
int EraseSector (unsigned long adr) {
/* Add your Code */
adr -= SPI_FLASH_MEM_ADDR;
BSP_W25qxx_Erase_Sector(adr);
return (0); // Finished without Errors
}
写入函数:
int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
/* Add your Code */
adr -= SPI_FLASH_MEM_ADDR;
B_W25qxx_Write(buf,adr,sz);
return (0); // Finished without Errors
}
添加校验函数:
unsigned long Verify(unsigned long adr, unsigned long sz, unsigned char *buf)
{
adr -= SPI_FLASH_MEM_ADDR;
adr += SPI_FLASH_MEM_ADDR;
return (adr + sz); /* 校验成功 */
}
注意:当前检验函数未作任何操作,只是为了下载时如果选择“Verify”了,依旧可以正常下载。
添加块擦除检查函数:
int BlankCheck(unsigned long adr, unsigned long sz, unsigned char pat)
{
// adr -= SPI_FLASH_MEM_ADDR;
/* 强制擦除 */
return 1;
}
注意:当前块擦除检查函数依旧未做任何操作。
⑤完成以上操作则修改完成,点击编译,生成FLM文件。
4、FLM下载算法验证
打开一份测试代码工程。
①修改测试工程设置,以下方式二选一。
方式一:打开“魔术棒”,Linker页面下,做出如下修改,
然后点击“Edit”,对.sct文件进行修改,在末尾添加如下代码:
LR_EROM1 0x90000000 0x00200000 { ; load region size_region
ER_EROM1 0x90000000 0x00200000 { ; load address = execution address
*(USE_EXT_FLASH_2MB_BUF_SPACE)
}
}
方式二:Traget页面,添加对应外部FLASH的虚拟地址和大小,如下图,
以上两种方式设置任意一种之后,进入下载设置界面,添加我们的FLM算法,然后将RAM空间暂时改大,否则算法下不进去(算法是下载到MCU中运行的),如下图,
②在测试工程中添加代码
实现将静态全局变量的值存储在外部FLASH中。
为了适配编译器,不然参数被编译器优化掉,定义宏:
#ifdef __CC_ARM /* ARM Compiler */
#define SECTION(x) __attribute__((section(x)))
#define USED __attribute__((used))
#define UNUSEDX __attribute__((unused))
#elif defined (__IAR_SYSTEMS_ICC__) /* for IAR Compiler */
#define SECTION(x) @ x
#define USED __root
#elif defined (__GNUC__) /* GNU GCC Compiler */
#define SECTION(x) __attribute__((section(x)))
#define USED __attribute__((used))
#define UNUSED __attribute__((unused))
#else
#error not supported tool chain
#endif /* __CC_ARM */
之后定义静态全局变量:
USED static const uint16_t Flash_Value SECTION("USE_EXT_FLASH_2MB_BUF_SPACE") = 0x1010;
5、连接实际板子点击下载即可。
附加说明:
1、可尝试屏蔽一些无用的库代码,例如内部flash的HAL代码,这样可以减小代码量,因为算法是临时加载到RAM中运行。
2、如遇到如下问题:
文章来源:https://www.toymoban.com/news/detail-833263.html
说明FLM算法存在问题,可尝试把自写的驱动代码屏蔽掉测试看看,屏蔽掉之后依旧不正常则可能是时钟设置或系统初始不对;屏蔽之后正常,则可能是IO初始化不对。文章来源地址https://www.toymoban.com/news/detail-833263.html
到了这里,关于STM32 HAL库形式制作SPI Flash(W25Q16)的 Keil下载算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!