STM32系列内部Flash擦写程序

stm32内部Flash擦写流程,对于FLash必须按页擦写,不同型号的flash页大小不同,需要根据实际修改

#define FLASH_PAGE_SIZE         2048    //定义Flash页大小,RCT6页大小为2K(2048),c8t6为1k(1024)

/*
 *对STM32内部FLASH写进行编程操作,需要遵循以下流程:
 *1.FLASH解锁
 *2.清除相关标志位
 *3.擦除FLASH(先擦除后写入的原因是为了工业上制作方便,即物理实现方便)
 *4.写入FLASH
 *5.锁定FLASH
*/
//计算需要擦除的页数
static uint32_t FLASH_PagesMask(uint32_t len)
{
    uint32_t pagenumber = 0;

    if ((len % FLASH_PAGE_SIZE) != 0)
    {
        pagenumber = (len / FLASH_PAGE_SIZE) + 1;
    }
    else
    {
        pagenumber = len / FLASH_PAGE_SIZE;
    }
    return pagenumber;
}
//向startAddr地址写入p_data数据,长度为len个字节,Earse_flag为1表示需要擦除Flash,返回0表示写入成功
uint8_t flash_write(uint32_t startAddr,uint8_t *p_data,uint32_t len,uint8_t Earse_flag)
{
    volatile FLASH_Status FLASHStatus;       //FLASH状态
    uint32_t EndAddr = startAddr + len;          //末地址
    uint32_t NbrOfPage = 0;
    uint32_t EraseCounter = 0x0, Address = 0x0;
    uint16_t MemoryProgramStatus = 0,i;
    uint32_t writeData;

    FLASH_Unlock();                   //FLASH解锁
    //清除所有已有标志
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
  
    if(Earse_flag)
    {
        //擦除
        NbrOfPage = FLASH_PagesMask(len);  //有多少个页被擦除
        
        FLASHStatus = FLASH_COMPLETE; 
        for(EraseCounter = 0;(EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
        {
            FLASHStatus = FLASH_ErasePage(startAddr+(FLASH_PAGE_SIZE*EraseCounter));
        }
        if(FLASHStatus!=FLASH_COMPLETE)
        {
            return 1;
        }
    }
    else 
    {
        FLASHStatus = FLASH_COMPLETE; 
    }
  
    Address = startAddr;
    
    for(i = 0; (Address < EndAddr) && (FLASHStatus==FLASH_COMPLETE); Address += 4)     //+=2
    {
        writeData = p_data[i]|(p_data[i+1]<<8)|(p_data[i+2]<<16)|(p_data[i+3]<<24);
        FLASHStatus=FLASH_ProgramWord(Address,writeData);  
        i += 4;
    }
    if(FLASHStatus!=FLASH_COMPLETE)
    {
        return 1;
    }
    FLASH_Lock();
  
    Address = startAddr;
    for(i = 0 ;(Address < EndAddr) && (MemoryProgramStatus != 1);Address += 1)
    {
        if((*(vu8*)Address != p_data[i++]))
        {
          MemoryProgramStatus = 1;
          return 1;
        }
    }
    return 0;  
}

void flash_read(uint32_t startAddr,uint8_t *p_data,uint16_t len)
{
    uint32_t address = startAddr;
    uint16_t i;

    for(i=0; i < len; i++)
    {
        p_data[i] = (*(vu8*)address);
        address++;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值