[RISC-V MCU 创新应用比赛] 第二部分:实现对CH32V103芯片内部Flash的控制

[复制链接]
4148|6
 楼主| 一路向北lm 发表于 2021-8-12 23:49 | 显示全部楼层 |阅读模式
上锁与解锁,上锁就是操作FLASH->CTLR寄存器,赋值为CR_LOCK_Set,而解锁便是两次往FLASH->KEYR 写入FLASH_KEY1与FLASH_KEY2的值。需要注意的是每次操作内部FLASH都需要解锁,操作完成后再对内部FLASH上锁。
  1. void FLASH_Lock(void)
  2. {
  3.   FLASH->CTLR |= CR_LOCK_Set;
  4. }

  5. void FLASH_Unlock(void)
  6. {
  7.   FLASH->KEYR = FLASH_KEY1;
  8.   FLASH->KEYR = FLASH_KEY2;
  9. }


 楼主| 一路向北lm 发表于 2021-8-13 00:02 | 显示全部楼层
页擦除与全片擦除,一般在烧录前会对芯片进行部分擦除或者全片擦除,这个根据需求来调取函数,具体分析大家可以参考FLASH相关的寄存器。
  1. FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
  2. {
  3.   FLASH_Status status = FLASH_COMPLETE;
  4.   status = FLASH_WaitForLastOperation(EraseTimeout);
  5.   if(status == FLASH_COMPLETE)
  6.   {
  7.     FLASH->CTLR|= CR_PER_Set;
  8.     FLASH->ADDR = Page_Address;
  9.     FLASH->CTLR|= CR_STRT_Set;
  10. status = FLASH_WaitForLastOperation(EraseTimeout);
  11.     FLASH->CTLR &= CR_PER_Reset;
  12.   }
  13.   *(__IO uint32_t*)0x40022034 = *(__IO uint32_t*)((Page_Address & 0xFFFFFFFC) ^ 0x00001000);
  14.   return status;
  15. }

  16. FLASH_Status FLASH_EraseAllPages(void)
  17. {
  18.   FLASH_Status status = FLASH_COMPLETE;
  19.   status = FLASH_WaitForLastOperation(EraseTimeout);
  20.   if(status == FLASH_COMPLETE)
  21.   {
  22.      FLASH->CTLR |= CR_MER_Set;
  23.      FLASH->CTLR |= CR_STRT_Set;
  24.     status = FLASH_WaitForLastOperation(EraseTimeout);
  25.     FLASH->CTLR &= CR_MER_Reset;
  26.   }
  27.   return status;
  28. }


 楼主| 一路向北lm 发表于 2021-8-13 20:26 | 显示全部楼层
Falsh写字和半字操作,无论是写字和半字需要注意的是,写之前需要打开写保护。
  1. FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
  2. {
  3.   FLASH_Status status = FLASH_COMPLETE;
  4.   status = FLASH_WaitForLastOperation(ProgramTimeout);
  5.   if(status == FLASH_COMPLETE)
  6.   {
  7.     FLASH->CTLR |= CR_PG_Set;
  8.     *(__IO uint16_t*)Address = Data;
  9.     status = FLASH_WaitForLastOperation(ProgramTimeout);
  10.     FLASH->CTLR &= CR_PG_Reset;
  11.   }
  12.         *(__IO uint32_t*)0x40022034 = *(__IO uint32_t*)((Address & 0xFFFFFFFC) ^ 0x00001000);
  13.   return status;
  14. }

  15. FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
  16. {
  17.   FLASH_Status status = FLASH_COMPLETE;
  18.   __IO uint32_t tmp = 0;
  19.   status = FLASH_WaitForLastOperation(ProgramTimeout);
  20.   if(status == FLASH_COMPLETE)
  21.   {
  22.     FLASH->CTLR |= CR_PG_Set;
  23.     *(__IO uint16_t*)Address = (uint16_t)Data;
  24.     status = FLASH_WaitForLastOperation(ProgramTimeout);
  25.     if(status == FLASH_COMPLETE)
  26.     {
  27.       tmp = Address + 2;
  28.       *(__IO uint16_t*) tmp = Data >> 16;
  29.       status = FLASH_WaitForLastOperation(ProgramTimeout);
  30.       FLASH->CTLR &= CR_PG_Reset;
  31.     }
  32.     else
  33.     {
  34.       FLASH->CTLR &= CR_PG_Reset;
  35.     }
  36.   }   
  37.   *(__IO uint32_t*)0x40022034 = *(__IO uint32_t*)((Address & 0xFFFFFFFC) ^ 0x00001000);
  38.   return status;
  39. }


 楼主| 一路向北lm 发表于 2021-8-13 21:32 | 显示全部楼层
Falsh读操作就更加简单了,我们只需要定义一个指针,指向我们想要读取的Falsh地址就可以了,大致就如下所示:
  1. #define  FLASH_READ_START_ADDR      ((uint32_t)0x08010000)
  2. uint32_t  ReadData =  *(__IO uint32_t*) FLASH_READ_START_ADDR;

yujielun 发表于 2022-10-10 17:38 | 显示全部楼层
内部flash不足怎么办?      
10299823 发表于 2022-10-10 17:59 | 显示全部楼层
jtag引脚如何与芯片相连               
uiint 发表于 2022-10-10 20:28 | 显示全部楼层
Jlink 可以读取 CH32V103芯片内的FLASH程序代码吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

3837

帖子

81

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