基于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
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include "stm32f10x.h" #include "GPIOLIKE51.h" #define uint unsigned int #define uchar unsigned char #define CLOCK 72/8 //时钟=72M //函数声明 void GPIO_Configuration(void); /**************************************************************************** * 名 称:delay_us(u32 nus) * 功 能:微秒延时函数 * 入口参数:u32 us * 出口参数:无 * 说 明: * 调用方法:无 ****************************************************************************/ //void delay_us(u32 us) //{ // u32 temp; // SysTick->LOAD = 9*us; // SysTick->VAL=0X00;//清空计数器 // SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 // do // { // temp=SysTick->CTRL;//读取当前倒计数值 // }while((temp&0x01;)&&(!(temp&(1<CTRL=0x00; //关闭计数器 // SysTick->VAL =0X00; //清空计数器 //} /**************************************************************************** * 名 称:delay_ms(u16 ms) * 功 能:毫秒延时函数 * 入口参数:u16 nms * 出口参数:无 * 说 明: * 调用方法:无 ****************************************************************************/ void delay_ms(u16 ms) { u32 temp; SysTick->LOAD = 9000*ms; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01;)&&(!(temp&(1<CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //============================================================================= //文件名称:main //功能概要:主函数 //参数说明:无 //函数返回:int //============================================================================= int main(void) { GPIO_Configuration(); while (1) { // GPIO_SetBits(GPIOB,GPIO_Pin_9); // delay_ms(500);// 100=0.1S GPIO_ResetBits(GPIOB,GPIO_Pin_9); delay_ms(500); } } //============================================================================= //文件名称:GPIO_Configuration //功能概要:GPIO初始化 //参数说明:无 //函数返回:无 //============================================================================= void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE&#4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值