打印
[方案相关]

【华大测评】为HC32F460外部Flash制作FLM

[复制链接]
3126|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
HC32F460开发板自带了一颗8M的FLASH:W25Q64,这么大的FLASH不装点什么感觉有点浪费,但是要装满的话需要单独写一个程序,这在实际开发中失衡麻烦的一件事。于是最近抽空做了一个FLM,分享给大家。大家也可以根据自己的需要自己写一个。
首先从keil安装目录下拷贝一份FLM模板工程:

再搜寻FlashOS.h,添加到模板工程中:

选择型号HC32F460PETB:

如图设置FlashDevice:

从官方例程中拷贝W25Qxx驱动至模板工程中:

再将相关文件如QSPI、CLK设置文件等拷贝至模板工程中:

如图设置Options:

添加相关文件至模板工程中:

按FlashPrg文件添加初始化,擦除与写函数:

编译生成FLM文件:

修改文件名并拷贝至keil/ARM/Flash中:

加载FLM文件。可以看到此时keil已识别FLM并可以加载了:


将IROM2设为W25Q64的地址:

编写一个大数组并设置地址为IROM2:

下载错误?看了一下是RAM for Algorithm设置小了:

增大RAM for Algorithm:

重新编译下载,可以通过Memory看到data常量成功写入:


最后说一下,W25Q64的驱动设置必须按如下设置,如果直接使用官方的配置,会发现写入的数据有误:

工程文件如下:
_Template.zip (98.62 KB)
HC32F460_QSPI.zip (4.35 MB)
HC32F460_QSPI_Download.zip (2.9 MB)
HC32F460_W25Qxx.zip (247.96 KB)

使用特权

评论回复
沙发
weifeng90| | 2021-12-5 17:44 | 只看该作者
这个不错,学习了。

使用特权

评论回复
板凳
chenjun89| | 2021-12-5 19:17 | 只看该作者
不错,谢谢楼主分享经验。

使用特权

评论回复
地板
WoodData| | 2021-12-6 09:40 | 只看该作者

不错,谢谢楼主分享经验。

使用特权

评论回复
5
cyclefly| | 2021-12-6 17:56 | 只看该作者
棒~~很不错啊

使用特权

评论回复
6
ddxx| | 2021-12-7 08:32 | 只看该作者
这个很好,谢谢了。

使用特权

评论回复
7
数码小叶| | 2021-12-8 14:26 | 只看该作者
不错,谢谢楼主分享经验。

使用特权

评论回复
8
andygirl| | 2021-12-8 16:21 | 只看该作者
厉害厉害,非常敬业

使用特权

评论回复
9
skyred| | 2022-1-19 15:55 | 只看该作者
了不起,感谢楼主的讲解

使用特权

评论回复
10
jheng| | 2022-7-19 17:18 | 只看该作者
if (memcmp(data, pFlashReadAddr, (uint32_t)bufferLen) != 0)
一次性比较27421个字节可以比较吗?为啥还要4k一次处理

使用特权

评论回复
11
纪国圣|  楼主 | 2022-7-19 17:42 | 只看该作者
jheng 发表于 2022-7-19 17:18
if (memcmp(data, pFlashReadAddr, (uint32_t)bufferLen) != 0)
一次性比较27421个字节可以比较吗?为啥还 ...

这样写的原因是如果有错误可以确定出错的位置,同时如果一次性检查那么多字节,内存不一定够用,最后你还要考虑程序的可移植。

使用特权

评论回复
12
jheng| | 2022-7-20 09:57 | 只看该作者
纪国圣 发表于 2022-7-19 17:42
这样写的原因是如果有错误可以确定出错的位置,同时如果一次性检查那么多字节,内存不一定够用,最后你还 ...

我的意思是程序看着是一次性比较的,bufferlen并不是4k

使用特权

评论回复
13
jheng| | 2022-7-20 10:59 | 只看该作者

没有设置断点,但是报这个错误

使用特权

评论回复
14
towp007| | 2022-7-21 23:08 | 只看该作者
烧录的时候需要把校验去掉才不报错误,也无法仿真查看烧录对没有,希望楼主能够再讲清楚一些。

1.我使用2线的QSPI在外面把驱动测试 能够使用,烧录的时候那0x20000 设置不了这么大,不超过65536.

使用特权

评论回复
15
纪国圣|  楼主 | 2022-7-23 09:32 | 只看该作者
本帖最后由 纪国圣 于 2022-7-23 09:49 编辑
jheng 发表于 2022-7-20 09:57
我的意思是程序看着是一次性比较的,bufferlen并不是4k

重温了一遍程序,你指出的部分确实有点问题,从通用性考虑应该4K一比较,并且在flashAddr += FLASH_SECTOR_SIZE;后面加上一个指向data[]数组的指针偏移。这样比较好。这里偷了个懒,先获取外部FLASH存储位置的指针,然后与data直接比较,这在大数据量下容易出问题。容易误解的地方是
flashAddr += FLASH_SECTOR_SIZE;
            if (flashAddr >= FLASH_MAX_ADDR)
            {
                flashAddr = 0u;
            }
其实在这个测试程序中是没必要的,当时移植没删掉,给大家造成误解,抱歉。
感谢指出错误。

使用特权

评论回复
16
纪国圣|  楼主 | 2022-7-23 09:34 | 只看该作者
jheng 发表于 2022-7-20 10:59
没有设置断点,但是报这个错误

我这边没有重现这个错误,所以没办法提出有效的建议。我这边是用的是V5.31版本。可以换个版本试试。

使用特权

评论回复
17
纪国圣|  楼主 | 2022-7-23 10:05 | 只看该作者
本帖最后由 纪国圣 于 2022-7-23 10:17 编辑
towp007 发表于 2022-7-21 23:08
烧录的时候需要把校验去掉才不报错误,也无法仿真查看烧录对没有,希望楼主能够再讲清楚一些。

1.我使用2 ...

烧录的时候那0x20000 设置不了这么大?工程其他地方有没有修改?至于烧录后是否正确,写一个比较函数,如:
const uint8_t data[] = {数据};
uint32_t flashAddr = 0u;
uint8_t *pDataAddr = data;
uint8_t *pFlashReadAddr = (uint8_t *)((uint32_t)QSPI_BUS_ADDRESS);
uint32_t i = 0;
for (i = 0;i < 最大的sector;i++)
{
        pFlashReadAddr = (uint8_t *)((uint32_t)QSPI_BUS_ADDRESS + flashAddr);
        /* Compare txBuffer and flash */
        if (memcmp(pDataAddr, pFlashReadAddr, FLASH_SECTOR_SIZE) != 0)
        {
                失败
        }
        else
        {
                成功
        }
       
        flashAddr += FLASH_SECTOR_SIZE;
        pDataAddr+= FLASH_SECTOR_SIZE;
}



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

401

帖子

5

粉丝