基于stm32f103的flash存储程序

#include "stm32f10x.h"

/* 定义Flash存储器的页大小和起始地址 */
#ifdef STM32F10X_LD
  #define FLASH_PAGE_SIZE    (uint32_t)0x400
  #define FLASH_START_ADDR   (uint32_t)0x08000000
#elif defined(STM32F10X_MD) || defined(STM32F10X_HD)
  #define FLASH_PAGE_SIZE    (uint32_t)0x800
  #define FLASH_START_ADDR   (uint32_t)0x08000000
#elif defined(STM32F10X_CL)
  #define FLASH_PAGE_SIZE    (uint32_t)0x800
  #define FLASH_START_ADDR   (uint32_t)0x08008000
#endif

/* 
 * 将数据写入Flash存储器
 * address:Flash存储器地址
 * data:存储要写入Flash存储器的数据的数组的指针
 * len:数据数组的长度(数据项的数量)
 * 返回值:0表示成功,1表示失败
 */
uint32_t Flash_WriteData(uint32_t address, uint32_t* data, uint32_t len) {
    FLASH_Status flashStatus = FLASH_COMPLETE;
    uint32_t pageAddress = address;
    uint32_t pageIndex = 0;
    uint32_t pageOffset = 0;

    /* 解锁Flash */
    FLASH_Unlock();

    /* 擦除一页,将地址和指针设为起始地址 */
    pageIndex = (address - FLASH_START_ADDR) / FLASH_PAGE_SIZE;
    pageAddress = FLASH_START_ADDR + pageIndex * FLASH_PAGE_SIZE;
    flashStatus = FLASH_ErasePage(pageAddress);
    while(flashStatus != FLASH_COMPLETE) {
        FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
        flashStatus = FLASH_ErasePage(pageAddress);
    }
    pageOffset = address - pageAddress;

    /* 写入数据 */
    for(uint32_t i = 0; i < len; i++) {
        uint32_t value = data[i];
        flashStatus = FLASH_ProgramWord(address, value);
        if(flashStatus != FLASH_COMPLETE) {
            FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
            FLASH_Lock();
            return 1;
        }

        address += 4;
        pageOffset += 4;

        /* 如果当前页写满了,则需要刷新下一页 */
        if(pageOffset >= FLASH_PAGE_SIZE) {
            pageOffset = 0;
            pageIndex++;
            pageAddress = FLASH_START_ADDR + pageIndex * FLASH_PAGE_SIZE;
            flashStatus = FLASH_ErasePage(pageAddress);
            while(flashStatus != FLASH_COMPLETE) {
                FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
                flashStatus = FLASH_ErasePage(pageAddress);
            }
        }
    }

    /* 锁定Flash */
    FLASH_Lock();

    /* 成功 */
    return 0;
}

int main(void) {
    uint32_t address = FLASH_START_ADDR;
    uint32_t data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    uint32_t len = sizeof(data) / sizeof(data[0]);

    /* 将数据写入Flash存储器 */
    uint32_t result = Flash_WriteData(address, data, len);

    /* 如果写入成功,则读取数据 */
    if(result == 0) {
        uint32_t* ptr = (uint32_t*)FLASH_START_ADDR;
        for(uint32_t i = 0; i < len; i++) {
            uint32_t value = *ptr;
            ptr++;
        }
    }

    while(1) {
    }
}

在这个例子中,我们使用了条件编译指令来自动选择不同型号的单片机所需的Flash存储器的页大小和起始地址。这样可以在不修改代码的情况下,将此代码移植到不同型号的单片机中,实现不同内存大小的存储器操作功能。

仅用于学习交流,不足之处请留言指正。交流优化

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值