内部flash写入的时候,需要将代码分配到内存中执行 
 
 
/************************************************************************************************************* 
 * 文件名                :        hc32f46x_flash.c 
 * 功能                        :        HC32F46X 内部FLASH驱动 
 * 作者                        :        cp1300@139.com 
 * 创建时间                :        2021-07-27 
 * 最后修改时间        :        2021-07-27 
 * 详细                        :        flash操作时要禁止一切中断以及flash读取操作,相关接口函数都要定义到RAM中执行,不要调用任何其他函数 
                                        连续编程过程中,绝对不能调用非RAM函数,目前是先清除看门狗(有12秒以上时间),保证擦除时间不超过12秒即可 
                                        2021-10-09:解决了可能存在的读写错误,原因是擦写flash的时候访问了flash导致; 
*************************************************************************************************************/ 
#include "hc32f46x.h" 
#include "hc32f46x_map.h" 
#include "system.h" 
#include "hc32f46x_flash.h" 
  
#define __at__IRAM3__                __attribute__((section("IRAM3"))) 
  
//FLASH编程模式 
typedef enum 
{ 
        PEMOD_READ_ONLY                 =         0,        //只读模式 
        PEMOD_SINGLE_PROGRAM        =        1,        //单编程模式 
        PEMOD_SINGLE_PROGRAM_RB        =        2,        //单编程回读模式 
        PEMOD_SEQUENCE_PROGRAM        =        3,        //连续编程模式 
        PEMOD_SECTOR_ERASE                =        4,        //扇区擦除模式 
        PEMOD_MASS_ERASE                =        5,        //全擦除模式 
}FLASH_PEMOD; 
  
  
/************************************************************************************************************************* 
* 函数                        :        void HC32FLASH_Unlock(void) 
* 功能                        :        解锁HC32的FLASH编程 
* 参数                        :        无 
* 返回                        :        无 
* 依赖                        :        底层 
* 作者                        :        cp1300@139.com 
* 时间                        :        2021-07-28 
* 最后修改时间         :         2021-07-28 
* 说明                        :         解锁配置,并进入编程模式 
*************************************************************************************************************************/ 
__at__IRAM3__ 
void HC32FLASH_Unlock(void) 
{ 
        SYS_EFM_CONFIG_Unlock();                //EFM配置解锁 
        EFM->FWMC |= BIT0;                                //允许修改编程模式 
        EFM->FWMC &= ~BIT8;                                //FLASH编程擦除期间,总线被占用 
} 
  
/************************************************************************************************************************* 
* 函数                        :        void HC32FLASH_Lock(void) 
* 功能                        :        上锁HC32的FLASH 
* 参数                        :        无 
* 返回                        :        无 
* 依赖                        :        底层 
* 作者                        :        cp1300@139.com 
* 时间                        :        2013-10-20 
* 最后修改时间         :         2018-01-13 
* 说明                        :         上锁配置,并退出编程模式 
*************************************************************************************************************************/ 
__at__IRAM3__ 
void HC32FLASH_Lock(void) 
{ 
        EFM->FWMC &= ~BIT0;                                        //不允许修改编程模式 
        SYS_EFM_CONFIG_Lock();                                //EFM配置上锁 
} 
  
  
/************************************************************************************************************************* 
* 函数                        :        HC32FLASH_STATUS HC32FLASH_GetStatus(void) 
* 功能                        :        得到FLASH状态 
* 参数                        :        无 
* 返回                        :        HC32FLASH_STATUS 
* 依赖                        :        底层 
* 作者                        :        cp1300@139.com 
* 时间                        :        2021-07-27 
* 最后修改时间         :         2021-07-27 
* 说明                        :          
*************************************************************************************************************************/ 
__at__IRAM3__ 
HC32FLASH_STATUS HC32FLASH_GetStatus(void) 
{         
        u32 temp=EFM->FSR;  
         
        if(!(temp&(1<<8))) return HC32FLASH_BUSY;                //忙 
        else if(temp&(1<<1))return HC32FLASH_WPRERR;        //写保护错误 
        else if(temp&(1<<2))return HC32FLASH_PGAERR;        //编程对齐错误 
        else if(temp&(1<<0))return HC32FLASH_PEWERR;        //在擦写不许可模式下擦写 FLASH 
        else if(temp&(1<<5))return HC32FLASH_COLERR;        //读写访问错误 
        else if(temp&(1<<3))return HC32FLASH_PGMISMTCH;        //单编程回读错误 
        return HC32FLASH_OK;                                                        //操作完成 
} 
  
  
/************************************************************************************************************************* 
* 函数                        :        HC32FLASH_STATUS HC32FLASH_WaitDone(u32 time) 
* 功能                        :        等待操作完成 
* 参数                        :        time:要延时的长短,单位us 
* 返回                        :        HC32FLASH_STATUS 
* 依赖                        :        底层 
* 作者                        :        cp1300@139.com 
* 时间                        :        2021-07-27 
* 最后修改时间         :         2021-07-27 
* 说明                        :          
*************************************************************************************************************************/ 
__at__IRAM3__ 
HC32FLASH_STATUS HC32FLASH_WaitDone(u32 time) 
{ 
        HC32FLASH_STATUS status; 
        u32 i; 
         
        if(time < 1) time = 1; 
        do 
        { 
                status=HC32FLASH_GetStatus();                        //获取状态 
                if(status!=HC32FLASH_BUSY)break;                //非忙,无需等待了,直接退出. 
                for(i = 0;i < 100;i ++) 
                { 
                        nop;nop;nop;nop;nop; 
                } 
                time--;                 
         }while(time); 
  
         return status; 
} 
  
  
  
/************************************************************************************************************************* 
* 函数                        :        void HC32FLASH_SetErasePgmMode(FLASH_PEMOD mode) 
* 功能                        :        设置flash的擦除编程模式 
* 参数                        :        mode:模式,见FLASH_PEMOD 
* 返回                        :        无 
* 依赖                        :        底层 
* 作者                        :        cp1300@139.com 
* 时间                        :        2021-07-28 
* 最后修改时间         :         2021-07-28 
* 说明                        :         必须先解锁才能调用 
*************************************************************************************************************************/ 
__at__IRAM3__ 
void HC32FLASH_SetErasePgmMode(FLASH_PEMOD mode) 
{ 
        EFM->FWMC &= ~(0x7 << 4);                                //先清除之前配置 
        EFM->FWMC |= (mode & 0x07) << 4;                //重新设置 
} 
  
  
  
/************************************************************************************************************************* 
* 函数                        :        HC32FLASH_STATUS HC32FLASH_EraseSector(u32 u32Addr) 
* 功能                        :        扇区擦除 
* 参数                        :        u32Addr:要擦除的数据所在地址(擦除数据所在扇区) 
* 返回                        :        HC32FLASH_STATUS 
* 依赖                        :        底层 
* 作者                        :        cp1300@139.com 
* 时间                        :        2021-07-28 
* 最后修改时间         :         2021-07-28 
* 说明                        :          
*************************************************************************************************************************/ 
__at__IRAM3__ 
HC32FLASH_STATUS HC32FLASH_EraseSector(u32 u32Addr) 
{ 
        HC32FLASH_STATUS status; 
        u32  FRMC_Temp; 
  
        SYS_DisableIrq();                                                //关闭中断 
        EFM->FSCLR = 0x3F;                                                //清除所有错误标记 
        HC32FLASH_Unlock();                                        //解锁  
        FRMC_Temp = EFM->FRMC;                                        //记录之前寄存器值 
        if(FRMC_Temp & BIT16)                                        //使能了缓存,则先关闭 
        { 
                EFM->FRMC &= ~BIT16;                                //关闭缓存 
        } 
#if(SYS_WDG_EN_) //使能了看门狗 
                IWDG_Feed(); 
#endif //SYS_WDG_EN_         
        HC32FLASH_SetErasePgmMode(PEMOD_SECTOR_ERASE);        //进入扇区擦除模式 
        //擦除模式,必须在RAM中执行 
        *(uint32_t*)u32Addr = 0x12345678;                //往所在位置随便写个数据,触发擦除 
        status=HC32FLASH_WaitDone(1000000);                //等待操作结束,最大1s  
        //擦除结束了 
        EFM->FSCLR = 0x3F;                                                //清除所有错误标记 
        HC32FLASH_SetErasePgmMode(PEMOD_READ_ONLY);        //退出擦除模式 
        if(FRMC_Temp & BIT16)                                        //使能了缓存 
        { 
                EFM->FRMC |= BIT16 | BIT24;                        //开启缓存-并复位缓存 
        } 
        HC32FLASH_Lock();                                                //上锁 
         
        SYS_EnableIrq();                                                //使能中断 
        if(status != HC32FLASH_OK) 
        { 
                DEBUG("擦除扇区%d失败(错误:%d) \r\n",u32Addr, status); 
        } 
         
        return status;                                                        //返回状态 
} 
 
 
 
 
  
 
  
 
 |   
     
  
 |