| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 | #include <stdint.h>#include <string.h>#include "flash.h"#include "hw_cfg.h"/* USE_STM32F103RCT6(总大小256K, 即128页) */#define FLASH_PAGE_SIZE     2048        /* 一页的大小:2048 Byte */volatile FLASH_Status FLASHStatus;volatile ErrorStatus MemoryProgramStatus;//uc32 SysParaStartAddr = FLASH_ONCHIP_START;   /* FLASH的第127页起始地址 *///uc32 SysParaEndAddr   = FLASH_ONCHIP_END; /* FLASH的第127结束地址 */#define FLASH_WRProt_Pages0to61 0x7FFFFFFF#define FLASH_PAGE_MASK(x) ((x) & (0xFFFFF000 + FLASH_PAGE_SIZE))#define IS_FLASH_USER_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_ONCHIP_START) && ((ADDRESS) < FLASH_ONCHIP_END))/* ++++++++++++++++++++++++++++++++++++++++基本功能函数++++++++++++++++++++++++++++++++++++++++ */void WriteFlash(uint32_t address, uint8_t *Data, uint32_t len){    uint32_t i;    uint32_t FlashAddress = address;    uint8_t *pbuf = Data;    uint8_t wr_size = 4;    /* Check the parameters */    assert_param(IS_FLASH_ADDRESS(address));    assert_param(IS_FLASH_USER_ADDRESS(address));    /* Check the parameters */    if(!IS_FLASH_ADDRESS(address))        return;    if(!IS_FLASH_USER_ADDRESS(address))        return;    if(PWR_GetFlagStatus(PWR_FLAG_PVDO))        return;    /* 关闭中断 */    __set_PRIMASK(1);    FLASHStatus = FLASH_COMPLETE;    MemoryProgramStatus = SUCCESS;    /* Unlock the Flash Program Erase controller */    FLASH_Unlock();    /* Clear All pending flags */    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);    for(i = 0; i < len; i += 4)    {        uint32_t tmp_word = 0;        uint8_t *pword = (uint8_t *)&tmp_word;        if((len - i) < 4)        {            wr_size = len - i;        }        if(FlashAddress % 4)        {            memcpy(pword, (int *)((FlashAddress / 4) * 4), 4);            memcpy(&pword[FlashAddress % 4], &pbuf[i], wr_size);            FlashAddress = (FlashAddress / 4) * 4;        }        else        {            memcpy(&tmp_word, &pbuf[i], wr_size);        }        FLASHStatus = FLASH_ProgramWord(FlashAddress, tmp_word);        FlashAddress = FlashAddress + 4;        if(FLASHStatus != FLASH_COMPLETE)        {            break;        }    }    /* Lock the Flash Program Erase controller */    FLASH_Lock();    /* 开启中断 */    __set_PRIMASK(0);}/****************************************************************************************** *函数名称 : WriteFlash *函数说明 : 向片内Flash指定的页写数据(指定页为系统参数存储区的页) *输入参数 : *           address------地址 *           Data--------要写入的数据的地址(内存地址,即数组名或指针) *           len---------要写入的数据的长度 *返回值   : 无******************************************************************************************/void WriteFlashPlus(uint32_t address, uint8_t *Data, uint32_t len){    uint32_t i, k;    uint8_t tmp_buf[FLASH_PAGE_SIZE] = {0};    uint32_t FlashAddress = 0x00;    uint32_t tmp_word;    uint32_t offset;    /* Check the parameters */    assert_param(IS_FLASH_ADDRESS(address));    assert_param(IS_FLASH_USER_ADDRESS(address));    /* Check the parameters */    if(!IS_FLASH_ADDRESS(address))        return;    if(!IS_FLASH_USER_ADDRESS(address))        return;    if(PWR_GetFlagStatus(PWR_FLAG_PVDO))        return;    /* 关闭中断 */    __set_PRIMASK(1);    FLASHStatus = FLASH_COMPLETE;    MemoryProgramStatus = SUCCESS;    /* Unlock the Flash Program Erase controller */    FLASH_Unlock();    /* Clear All pending flags */    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);    /* 擦除后写数据 */    /* 读取要擦出页的数据到缓冲数组 */    for(i=0; i<FLASH_PAGE_SIZE; i++)    {        tmp_buf[i] = *((uint8_t *)(FLASH_PAGE_MASK(address) + i));    }    /* 执行擦除 */    FLASHStatus = FLASH_ErasePage(FLASH_PAGE_MASK(address));    /* 将数据写入到缓冲数组 */    offset = address - FLASH_PAGE_MASK(address);    for(i = 0; i < len;  i++)    {        tmp_buf[offset + i] = Data[i];    }    /* 从缓冲数组写到Flash */    k = 0;    FlashAddress = FLASH_PAGE_MASK(address);    while((k < FLASH_PAGE_SIZE) && (FlashAddress < FLASH_PAGE_MASK(address + FLASH_PAGE_SIZE)) && (FLASHStatus == FLASH_COMPLETE))    {        tmp_word = *(uint32_t *)&tmp_buf[k];        k += 4;        FLASHStatus = FLASH_ProgramWord(FlashAddress, tmp_word);        FlashAddress = FlashAddress + 4;    }    /* Lock the Flash Program Erase controller */    FLASH_Lock();    /* 开启中断 */    __set_PRIMASK(0);}/****************************************************************************************** *函数名称 : ReadFlash *函数说明 : 从片内Flash指定的页读数据(指定页为系统参数存储区的页) *输入参数 : *           address------地址 *           len---------要读出的数据的长度 *           Data--------存放读出的数据的地址(内存地址,即数组名或指针) *返回值   : 无******************************************************************************************/void ReadFlash(const uint32_t address, uint8_t *Data, uint32_t len){    uint32_t i;    /* Check the parameters */    assert_param(IS_FLASH_ADDRESS(address));    assert_param(IS_FLASH_USER_ADDRESS(address));    if(!IS_FLASH_ADDRESS(address))        return;    if(!IS_FLASH_USER_ADDRESS(address))        return;    /* 从Flash中读取所需数据到数组Data中 */    for(i=0; i<len; i++)    {        Data[i] = *((uint8_t *)(address + i));    }}void EraseFlash(uint32_t address){    /* Check the parameters */    assert_param(IS_FLASH_ADDRESS(address));    assert_param(IS_FLASH_USER_ADDRESS(address));    if(!IS_FLASH_ADDRESS(address))        return;    if(!IS_FLASH_USER_ADDRESS(address))        return;    if(PWR_GetFlagStatus(PWR_FLAG_PVDO))        return;    /* 关闭中断 */    __set_PRIMASK(1);    FLASHStatus = FLASH_COMPLETE;    MemoryProgramStatus = SUCCESS;    /* Unlock the Flash Program Erase controller */    FLASH_Unlock();    /* Clear All pending flags */    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);    /* 执行擦除 */    FLASHStatus = FLASH_ErasePage(FLASH_PAGE_MASK(address));    /* Lock the Flash Program Erase controller */    FLASH_Lock();    /* 开启中断 */    __set_PRIMASK(0);}void Flash_ReadProtection(void){    /* Flash读保护使能 */    if (FLASH_GetReadOutProtectionStatus() == RESET)    {        FLASH_Unlock();        FLASH_ReadOutProtection(ENABLE);    }}
 |