打印
[技术问答]

请教怎样对HC32F460 flash进行读写操作

[复制链接]
3933|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
请教怎样对HC32F460 flash进行读写操作?

HC32F17-19支持对FLASH进行Byte(8位), half-word(16位)和word(32位)三种数据宽度读写。而且给出了例子DEMO。

这个HC32F490好像只能128位读写。请问有8位数组 Byte[16]读写的参考代码嘛

使用特权

评论回复
沙发
zhengshuai888| | 2021-4-18 15:07 | 只看该作者
官方应该有Flash操作应用代码库吧

使用特权

评论回复
板凳
lidi911| | 2021-4-18 15:36 | 只看该作者
参照一下官方的应用例程

使用特权

评论回复
地板
嵌入小菜菜| | 2021-4-18 21:52 | 只看该作者
直接参考官网的例程,是不是会更好一些呢

使用特权

评论回复
5
martinhu| | 2021-4-19 09:29 | 只看该作者
F460编程时候是字编程,也就是32bit,读的话字、半字或者字节都可以,
楼主看的是关于取指的内容吗?
128bit说的是取指的位宽,一次可以读取4条32bit指令,或8条16bit指令……这样取指一般来说效率会更高。

使用特权

评论回复
6
nongfuxu|  楼主 | 2021-4-21 09:06 | 只看该作者
zhengshuai888 发表于 2021-4-18 15:07
官方应该有Flash操作应用代码库吧

HC32F460没FLASH代码库

使用特权

评论回复
7
nongfuxu|  楼主 | 2021-4-21 09:07 | 只看该作者
嵌入小菜菜 发表于 2021-4-18 21:52
直接参考官网的例程,是不是会更好一些呢

HC32F460没FLASH代码库

使用特权

评论回复
8
nongfuxu|  楼主 | 2021-4-21 09:09 | 只看该作者
martinhu 发表于 2021-4-19 09:29
F460编程时候是字编程,也就是32bit,读的话字、半字或者字节都可以,
楼主看的是关于取指的内容吗?
128bi ...

哪里可以找到HC32F460的FLASH例子代码呀?

使用特权

评论回复
9
martinhu| | 2021-4-21 11:23 | 只看该作者
nongfuxu 发表于 2021-4-21 09:09
哪里可以找到HC32F460的FLASH例子代码呀?

官网不是有F460的驱动库和样例吗?

使用特权

评论回复
10
martinhu| | 2021-4-21 11:23 | 只看该作者
nongfuxu 发表于 2021-4-21 09:07
HC32F460没FLASH代码库

有的,叫EFM……

使用特权

评论回复
11
nongfuxu|  楼主 | 2021-4-21 15:11 | 只看该作者
EFM模块  ,嵌入式 FLASH(EFM)

使用特权

评论回复
12
nongfuxu|  楼主 | 2021-4-21 15:15 | 只看该作者
本帖最后由 nongfuxu 于 2021-4-21 21:22 编辑
nongfuxu 发表于 2021-4-21 15:11
EFM模块  ,嵌入式 FLASH(EFM)

HC32F460芯片读写闪存太难了

使用特权

评论回复
13
nawu| | 2021-5-11 20:35 | 只看该作者
这样跨度也太大了吧

使用特权

评论回复
14
qcliu| | 2021-5-11 20:36 | 只看该作者
还没有进行过flash操作

使用特权

评论回复
15
tfqi| | 2021-5-11 20:36 | 只看该作者
没有其他位的操作吗

使用特权

评论回复
16
wiba| | 2021-5-11 20:37 | 只看该作者
官方应该有Flash操作应用代码

使用特权

评论回复
17
zljiu| | 2021-5-11 20:37 | 只看该作者
直接参考官网的例程

使用特权

评论回复
18
axman002| | 2021-7-3 14:53 | 只看该作者
这个HC32F460手册上说只能执行扇区擦除。而一个扇区就是8K字节啊。有没有办法只擦除指定地址的数据?

使用特权

评论回复
评论
wubangmi 2021-10-9 15:03 回复TA
除了铁电我没用过,没看到过有哪款FLASH能单独擦指定一个地址的数据的, 
wubangmi 2021-10-9 15:03 回复TA
除了铁电我没用过,没看到过有哪款FLASH能单独擦指定一个地址的数据的, 
19
nczywq| | 2021-10-12 10:19 | 只看该作者
axman002 发表于 2021-7-3 14:53
这个HC32F460手册上说只能执行扇区擦除。而一个扇区就是8K字节啊。有没有办法只擦除指定地址的数据? ...

nor flash 擦除都是一整块的,你看现的flash都有均衡算法,楼主我自己设计的板子上外挂了一个spi的norflash,内部操作大同小异,可以实现任意地位置写数据,不影响其他的数据。代码如下,供参考
int w25qxxwrite(uint8_t * buff , uint32_t writeAddr , uint16_t count)
{
        /*
                stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
                flashnoreading = 1 ;                //flash 禁止读取
                QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取   
        */
       
        /*
                stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
                flashnoreading = 0 ;    //读取模式
                QSPI_CommProtocolConfig(&stcQspiCommProtocol);
        */
       
        uint8_t w25qxxbuff[4096];    //一个块的数据缓存
        uint32_t sectorpos = writeAddr/4096;    //计算sector地址
        uint16_t secotroff = writeAddr%4096;                //计算sector偏移地址
       
        //下面先计算写入的数量占用了多个个sector
        uint32_t sectormain = secotroff + count ;
        uint16_t sectorcount= sectormain / 4096;                        //sector整数量
        uint16_t sectorwoff = sectormain % 4096;      //sector余数数量
       
        stc_qspi_comm_protocol_t stcQspiCommProtocol;
        MEM_ZERO_STRUCT(stcQspiCommProtocol);
       
        //先判断sector地址是否刚好等于falsh的sector开始地址
        if(secotroff == 0)                        //这表示刚好等于falsh sector的开始地址
        {
                uint8_t eraseflashsector = 0 ;
                for(uint16_t i = 0 ; i < sectorcount ; i += 1)               
                {
                        //先回到读取模式,这里的目的是判断sector是否要擦除
                        stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
                        flashnoreading = 0 ;    //读取模式
                        QSPI_CommProtocolConfig(&stcQspiCommProtocol);
                        w25qxxread(w25qxxbuff,sectorpos * 4096 + i * 4096,4096);   //读取整个sector
                        for(uint16_t j = 0 ; j < 4096 ; j += 1)
                        {
                                if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
                                {
                                        eraseflashsector = 1 ;
                                        break;
                                }
                        }
                        stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
                        flashnoreading = 1 ;                //flash 禁止读取
                        QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取  
                        if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096 + i * 4096 ); //擦除整个secotr
                        for(uint8_t k = 0 ; k < 16 ; k += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
                        {
                                QspiFlash_WritePage(sectorpos * 4096 + i * 4096 + k * 256 ,buff,256);                //这里的buff要随着写入数据的偏移而偏移
                                buff += 256;
                        }
                }
                if(sectorwoff != 0 )                        //整个sector操作结束后,要判断有没有下一个sector要操作还不是整个sector
                {
                        //先回到读取模式,这里的目的是判断sector是否要擦除
                        stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
                        flashnoreading = 0 ;    //读取模式
                        QSPI_CommProtocolConfig(&stcQspiCommProtocol);
                        w25qxxread(w25qxxbuff,sectorpos * 4096 + sectorcount * 4096,4096);   //读取整个sector
       
                        stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
                        flashnoreading = 1 ;                //flash 禁止读取
                        QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取  
                        QspiFlash_Erase4KbSector(sectorpos * 4096 + sectorcount * 4096); //擦除整个secotr
                        //下面修改数据
                        for(uint16_t i = 0 ; i < sectorwoff ; i += 1)
                        {
                                w25qxxbuff[i] = *(buff++);
                        }
                        //下面把修改好的数据分16次写入flash
                        for(uint8_t i = 0 ; i < 16 ; i += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
                        {
                                QspiFlash_WritePage(sectorpos * 4096 + sectorcount * 4096 + i * 256 ,w25qxxbuff + i * 256,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
                        }
                }
        }
        else        //这是地址位置不是在sector的头地址
        {
                if(sectorcount == 0  || (sectorcount == 1 && sectorwoff == 0))                //只有一个secotr时的操作
                {
                        uint8_t eraseflashsector = 0 ;
                        //先回到读取模式,这里的目的是判断sector是否要擦除
                        stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
                        flashnoreading = 0 ;    //读取模式
                        QSPI_CommProtocolConfig(&stcQspiCommProtocol);
                        w25qxxread(w25qxxbuff,sectorpos * 4096 ,4096);   //读取整个sector
                        for(uint16_t j = 0 ; j < 4096 ; j += 1)
                        {
                                if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
                                {
                                        eraseflashsector = 1 ;
                                        break;
                                }
                        }
                        stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
                        flashnoreading = 1 ;                //flash 禁止读取
                        QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取
                        if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096); //擦除整个secotr
                        //下面修改数据
                        for(uint16_t j = secotroff ; j < sectormain ; j += 1)
                        {
                                w25qxxbuff[j] = *(buff++);
                        }
                        //下面把修改好的数据分16次写入flash
                        for(uint8_t j = 0 ; j < 16 ; j += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
                        {
                                QspiFlash_WritePage(sectorpos * 4096 + j * 256 ,w25qxxbuff + j * 256,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
                        }
                }
                else                //这是不止一个sector的时候处理
                {
                        //下面操作第一个sector
                        uint8_t eraseflashsector = 0 ;
                        //先回到读取模式,这里的目的是判断sector是否要擦除
                        stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
                        flashnoreading = 0 ;    //读取模式
                        QSPI_CommProtocolConfig(&stcQspiCommProtocol);
                        w25qxxread(w25qxxbuff,sectorpos * 4096 ,4096);   //读取整个sector
                        for(uint16_t j = 0 ; j < 4096 ; j += 1)
                        {
                                if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
                                {
                                        eraseflashsector = 1 ;
                                        break;
                                }
                        }
                        stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
                        flashnoreading = 1 ;                //flash 禁止读取
                        QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取
                        if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096); //擦除整个secotr
                        //下面修改数据
                        for(uint16_t j = secotroff ; j < 4096 ; j += 1)
                        {
                                w25qxxbuff[j] = *(buff++);
                        }
                        //下面把修改好的数据分16次写入flash
                        for(uint8_t j = 0 ; j < 16 ; j += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
                        {
                                QspiFlash_WritePage(sectorpos * 4096 + j * 256 ,w25qxxbuff + j * 256,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
                        }
                        //下面处理后面的sector
                        for(uint16_t i = 1 ; i < sectorcount ; i += 1)
                        {
                                //下面操作sector
                                eraseflashsector = 0 ;
                                //先回到读取模式,这里的目的是判断sector是否要擦除
                                stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
                                flashnoreading = 0 ;    //读取模式
                                QSPI_CommProtocolConfig(&stcQspiCommProtocol);
                                w25qxxread(w25qxxbuff,sectorpos * 4096 + i * 4096,4096);   //读取整个sector
                                for(uint16_t j = 0 ; j < 4096 ; j += 1)
                                {
                                        if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
                                        {
                                                eraseflashsector = 1 ;
                                                break;
                                        }
                                }
                                stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
                                flashnoreading = 1 ;                //flash 禁止读取
                                QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取
                                if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096 + i * 4096); //擦除整个secotr
                               
                                for(uint8_t j = 0 ; j < 16 ; j += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
                                {
                                        QspiFlash_WritePage(sectorpos * 4096 + i * 4096 + j * 256 ,buff,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
                                        buff += 256;
                                }
                        }
                        //处理剩余的数据
                        if(sectorwoff != 0)
                        {
                                eraseflashsector = 0 ;
                                //先回到读取模式,这里的目的是判断sector是否要擦除
                                stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
                                flashnoreading = 0 ;    //读取模式
                                QSPI_CommProtocolConfig(&stcQspiCommProtocol);
                                w25qxxread(w25qxxbuff,sectorpos * 4096 + sectorcount * 4096 ,4096);   //读取整个sector
                                for(uint16_t j = 0 ; j < 4096 ; j += 1)
                                {
                                        if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
                                        {
                                                eraseflashsector = 1 ;
                                                break;
                                        }
                                }
                                stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
                                flashnoreading = 1 ;                //flash 禁止读取
                                QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取
                                if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096 + sectorcount * 4096); //擦除整个secotr
                                //下面修改数据
                                for(uint16_t j = 0 ; j < sectorwoff ; j += 1)
                                {
                                        w25qxxbuff[j] = *(buff++);
                                }
                                //下面把修改好的数据分16次写入flash
                                for(uint8_t j = 0 ; j < 16 ; j += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
                                {
                                        QspiFlash_WritePage(sectorpos * 4096 + sectorcount * 4096 + j * 256 ,w25qxxbuff + j * 256,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
                                }
                        }
                }
        }
        stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
        QSPI_CommProtocolConfig(&stcQspiCommProtocol);
        flashnoreading = 0 ;    //这里重新回到读取模式
        return 0 ;
}

使用特权

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

本版积分规则

414

主题

4288

帖子

2

粉丝