[技术问答] 请教怎样对HC32F460 flash进行读写操作

[复制链接]
 楼主| nongfuxu 发表于 2021-4-17 16:41 | 显示全部楼层 |阅读模式
请教怎样对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 | 显示全部楼层
直接参考官网的例程,是不是会更好一些呢
martinhu 发表于 2021-4-19 09:29 | 显示全部楼层
F460编程时候是字编程,也就是32bit,读的话字、半字或者字节都可以,
楼主看的是关于取指的内容吗?
128bit说的是取指的位宽,一次可以读取4条32bit指令,或8条16bit指令……这样取指一般来说效率会更高。
82964607cdcdda5550.png
 楼主| nongfuxu 发表于 2021-4-21 09:06 | 显示全部楼层
zhengshuai888 发表于 2021-4-18 15:07
官方应该有Flash操作应用代码库吧

HC32F460没FLASH代码库
 楼主| nongfuxu 发表于 2021-4-21 09:07 | 显示全部楼层
嵌入小菜菜 发表于 2021-4-18 21:52
直接参考官网的例程,是不是会更好一些呢

HC32F460没FLASH代码库
 楼主| nongfuxu 发表于 2021-4-21 09:09 | 显示全部楼层
martinhu 发表于 2021-4-19 09:29
F460编程时候是字编程,也就是32bit,读的话字、半字或者字节都可以,
楼主看的是关于取指的内容吗?
128bi ...

哪里可以找到HC32F460的FLASH例子代码呀?
martinhu 发表于 2021-4-21 11:23 | 显示全部楼层
nongfuxu 发表于 2021-4-21 09:09
哪里可以找到HC32F460的FLASH例子代码呀?

官网不是有F460的驱动库和样例吗?
martinhu 发表于 2021-4-21 11:23 | 显示全部楼层
nongfuxu 发表于 2021-4-21 09:07
HC32F460没FLASH代码库

有的,叫EFM……
 楼主| nongfuxu 发表于 2021-4-21 15:11 | 显示全部楼层
EFM模块  ,嵌入式 FLASH(EFM)
 楼主| nongfuxu 发表于 2021-4-21 15:15 | 显示全部楼层
本帖最后由 nongfuxu 于 2021-4-21 21:22 编辑
nongfuxu 发表于 2021-4-21 15:11
EFM模块  ,嵌入式 FLASH(EFM)

HC32F460芯片读写闪存太难了
nawu 发表于 2021-5-11 20:35 | 显示全部楼层
这样跨度也太大了吧
qcliu 发表于 2021-5-11 20:36 | 显示全部楼层
还没有进行过flash操作
tfqi 发表于 2021-5-11 20:36 | 显示全部楼层
没有其他位的操作吗
wiba 发表于 2021-5-11 20:37 | 显示全部楼层
官方应该有Flash操作应用代码
zljiu 发表于 2021-5-11 20:37 | 显示全部楼层
直接参考官网的例程
axman002 发表于 2021-7-3 14:53 | 显示全部楼层
这个HC32F460手册上说只能执行扇区擦除。而一个扇区就是8K字节啊。有没有办法只擦除指定地址的数据?

评论

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

nor flash 擦除都是一整块的,你看现的flash都有均衡算法,楼主我自己设计的板子上外挂了一个spi的norflash,内部操作大同小异,可以实现任意地位置写数据,不影响其他的数据。代码如下,供参考
  1. int w25qxxwrite(uint8_t * buff , uint32_t writeAddr , uint16_t count)
  2. {
  3.         /*
  4.                 stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
  5.                 flashnoreading = 1 ;                //flash 禁止读取
  6.                 QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取   
  7.         */
  8.        
  9.         /*
  10.                 stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
  11.                 flashnoreading = 0 ;    //读取模式
  12.                 QSPI_CommProtocolConfig(&stcQspiCommProtocol);
  13.         */
  14.        
  15.         uint8_t w25qxxbuff[4096];    //一个块的数据缓存
  16.         uint32_t sectorpos = writeAddr/4096;    //计算sector地址
  17.         uint16_t secotroff = writeAddr%4096;                //计算sector偏移地址
  18.        
  19.         //下面先计算写入的数量占用了多个个sector
  20.         uint32_t sectormain = secotroff + count ;
  21.         uint16_t sectorcount= sectormain / 4096;                        //sector整数量
  22.         uint16_t sectorwoff = sectormain % 4096;      //sector余数数量
  23.        
  24.         stc_qspi_comm_protocol_t stcQspiCommProtocol;
  25.         MEM_ZERO_STRUCT(stcQspiCommProtocol);
  26.        
  27.         //先判断sector地址是否刚好等于falsh的sector开始地址
  28.         if(secotroff == 0)                        //这表示刚好等于falsh sector的开始地址
  29.         {
  30.                 uint8_t eraseflashsector = 0 ;
  31.                 for(uint16_t i = 0 ; i < sectorcount ; i += 1)               
  32.                 {
  33.                         //先回到读取模式,这里的目的是判断sector是否要擦除
  34.                         stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
  35.                         flashnoreading = 0 ;    //读取模式
  36.                         QSPI_CommProtocolConfig(&stcQspiCommProtocol);
  37.                         w25qxxread(w25qxxbuff,sectorpos * 4096 + i * 4096,4096);   //读取整个sector
  38.                         for(uint16_t j = 0 ; j < 4096 ; j += 1)
  39.                         {
  40.                                 if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
  41.                                 {
  42.                                         eraseflashsector = 1 ;
  43.                                         break;
  44.                                 }
  45.                         }
  46.                         stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
  47.                         flashnoreading = 1 ;                //flash 禁止读取
  48.                         QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取  
  49.                         if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096 + i * 4096 ); //擦除整个secotr
  50.                         for(uint8_t k = 0 ; k < 16 ; k += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
  51.                         {
  52.                                 QspiFlash_WritePage(sectorpos * 4096 + i * 4096 + k * 256 ,buff,256);                //这里的buff要随着写入数据的偏移而偏移
  53.                                 buff += 256;
  54.                         }
  55.                 }
  56.                 if(sectorwoff != 0 )                        //整个sector操作结束后,要判断有没有下一个sector要操作还不是整个sector
  57.                 {
  58.                         //先回到读取模式,这里的目的是判断sector是否要擦除
  59.                         stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
  60.                         flashnoreading = 0 ;    //读取模式
  61.                         QSPI_CommProtocolConfig(&stcQspiCommProtocol);
  62.                         w25qxxread(w25qxxbuff,sectorpos * 4096 + sectorcount * 4096,4096);   //读取整个sector
  63.        
  64.                         stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
  65.                         flashnoreading = 1 ;                //flash 禁止读取
  66.                         QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取  
  67.                         QspiFlash_Erase4KbSector(sectorpos * 4096 + sectorcount * 4096); //擦除整个secotr
  68.                         //下面修改数据
  69.                         for(uint16_t i = 0 ; i < sectorwoff ; i += 1)
  70.                         {
  71.                                 w25qxxbuff[i] = *(buff++);
  72.                         }
  73.                         //下面把修改好的数据分16次写入flash
  74.                         for(uint8_t i = 0 ; i < 16 ; i += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
  75.                         {
  76.                                 QspiFlash_WritePage(sectorpos * 4096 + sectorcount * 4096 + i * 256 ,w25qxxbuff + i * 256,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
  77.                         }
  78.                 }
  79.         }
  80.         else        //这是地址位置不是在sector的头地址
  81.         {
  82.                 if(sectorcount == 0  || (sectorcount == 1 && sectorwoff == 0))                //只有一个secotr时的操作
  83.                 {
  84.                         uint8_t eraseflashsector = 0 ;
  85.                         //先回到读取模式,这里的目的是判断sector是否要擦除
  86.                         stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
  87.                         flashnoreading = 0 ;    //读取模式
  88.                         QSPI_CommProtocolConfig(&stcQspiCommProtocol);
  89.                         w25qxxread(w25qxxbuff,sectorpos * 4096 ,4096);   //读取整个sector
  90.                         for(uint16_t j = 0 ; j < 4096 ; j += 1)
  91.                         {
  92.                                 if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
  93.                                 {
  94.                                         eraseflashsector = 1 ;
  95.                                         break;
  96.                                 }
  97.                         }
  98.                         stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
  99.                         flashnoreading = 1 ;                //flash 禁止读取
  100.                         QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取
  101.                         if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096); //擦除整个secotr
  102.                         //下面修改数据
  103.                         for(uint16_t j = secotroff ; j < sectormain ; j += 1)
  104.                         {
  105.                                 w25qxxbuff[j] = *(buff++);
  106.                         }
  107.                         //下面把修改好的数据分16次写入flash
  108.                         for(uint8_t j = 0 ; j < 16 ; j += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
  109.                         {
  110.                                 QspiFlash_WritePage(sectorpos * 4096 + j * 256 ,w25qxxbuff + j * 256,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
  111.                         }
  112.                 }
  113.                 else                //这是不止一个sector的时候处理
  114.                 {
  115.                         //下面操作第一个sector
  116.                         uint8_t eraseflashsector = 0 ;
  117.                         //先回到读取模式,这里的目的是判断sector是否要擦除
  118.                         stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
  119.                         flashnoreading = 0 ;    //读取模式
  120.                         QSPI_CommProtocolConfig(&stcQspiCommProtocol);
  121.                         w25qxxread(w25qxxbuff,sectorpos * 4096 ,4096);   //读取整个sector
  122.                         for(uint16_t j = 0 ; j < 4096 ; j += 1)
  123.                         {
  124.                                 if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
  125.                                 {
  126.                                         eraseflashsector = 1 ;
  127.                                         break;
  128.                                 }
  129.                         }
  130.                         stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
  131.                         flashnoreading = 1 ;                //flash 禁止读取
  132.                         QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取
  133.                         if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096); //擦除整个secotr
  134.                         //下面修改数据
  135.                         for(uint16_t j = secotroff ; j < 4096 ; j += 1)
  136.                         {
  137.                                 w25qxxbuff[j] = *(buff++);
  138.                         }
  139.                         //下面把修改好的数据分16次写入flash
  140.                         for(uint8_t j = 0 ; j < 16 ; j += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
  141.                         {
  142.                                 QspiFlash_WritePage(sectorpos * 4096 + j * 256 ,w25qxxbuff + j * 256,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
  143.                         }
  144.                         //下面处理后面的sector
  145.                         for(uint16_t i = 1 ; i < sectorcount ; i += 1)
  146.                         {
  147.                                 //下面操作sector
  148.                                 eraseflashsector = 0 ;
  149.                                 //先回到读取模式,这里的目的是判断sector是否要擦除
  150.                                 stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
  151.                                 flashnoreading = 0 ;    //读取模式
  152.                                 QSPI_CommProtocolConfig(&stcQspiCommProtocol);
  153.                                 w25qxxread(w25qxxbuff,sectorpos * 4096 + i * 4096,4096);   //读取整个sector
  154.                                 for(uint16_t j = 0 ; j < 4096 ; j += 1)
  155.                                 {
  156.                                         if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
  157.                                         {
  158.                                                 eraseflashsector = 1 ;
  159.                                                 break;
  160.                                         }
  161.                                 }
  162.                                 stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
  163.                                 flashnoreading = 1 ;                //flash 禁止读取
  164.                                 QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取
  165.                                 if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096 + i * 4096); //擦除整个secotr
  166.                                
  167.                                 for(uint8_t j = 0 ; j < 16 ; j += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
  168.                                 {
  169.                                         QspiFlash_WritePage(sectorpos * 4096 + i * 4096 + j * 256 ,buff,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
  170.                                         buff += 256;
  171.                                 }
  172.                         }
  173.                         //处理剩余的数据
  174.                         if(sectorwoff != 0)
  175.                         {
  176.                                 eraseflashsector = 0 ;
  177.                                 //先回到读取模式,这里的目的是判断sector是否要擦除
  178.                                 stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
  179.                                 flashnoreading = 0 ;    //读取模式
  180.                                 QSPI_CommProtocolConfig(&stcQspiCommProtocol);
  181.                                 w25qxxread(w25qxxbuff,sectorpos * 4096 + sectorcount * 4096 ,4096);   //读取整个sector
  182.                                 for(uint16_t j = 0 ; j < 4096 ; j += 1)
  183.                                 {
  184.                                         if(w25qxxbuff[j] != 0xff)                //该sector需要擦除
  185.                                         {
  186.                                                 eraseflashsector = 1 ;
  187.                                                 break;
  188.                                         }
  189.                                 }
  190.                                 stcQspiCommProtocol.enReadMode = QspiReadModeStandard;
  191.                                 flashnoreading = 1 ;                //flash 禁止读取
  192.                                 QSPI_CommProtocolConfig(&stcQspiCommProtocol);    //切换为写falsh模式,禁止读取
  193.                                 if(eraseflashsector) QspiFlash_Erase4KbSector(sectorpos * 4096 + sectorcount * 4096); //擦除整个secotr
  194.                                 //下面修改数据
  195.                                 for(uint16_t j = 0 ; j < sectorwoff ; j += 1)
  196.                                 {
  197.                                         w25qxxbuff[j] = *(buff++);
  198.                                 }
  199.                                 //下面把修改好的数据分16次写入flash
  200.                                 for(uint8_t j = 0 ; j < 16 ; j += 1)                //分16次写入数据,因为qspi flash 一次只能写入256个数据;
  201.                                 {
  202.                                         QspiFlash_WritePage(sectorpos * 4096 + sectorcount * 4096 + j * 256 ,w25qxxbuff + j * 256,256);                //这里的w25qxxbuff要随着写入数据的偏移而偏移
  203.                                 }
  204.                         }
  205.                 }
  206.         }
  207.         stcQspiCommProtocol.enReadMode = QspiReadModeFourWiresOutput;
  208.         QSPI_CommProtocolConfig(&stcQspiCommProtocol);
  209.         flashnoreading = 0 ;    //这里重新回到读取模式
  210.         return 0 ;
  211. }

您需要登录后才可以回帖 登录 | 注册

本版积分规则

417

主题

4295

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部