首页 » 嵌入式笔记 » 正文

STM32F10X 内部Flash当做EEPROM使用API

使用方法

直接修改以下宏以匹配不同芯片即可

#define MAX_SIZE     40960                              // 定义总共 40K的FLASH做为EEPROM用,必须为PAGE_SIZE的整数倍                        
#define PAGE_SIZE    2048                               // MD器件 1KB为1页   CL与HD为2KB
#define ADDR_OFFSET  (0x8000000+0x40000-MAX_SIZE)       // STM32 flash起始地址+总大小需要写的大小,需要注意的是不同芯片不一样

程序代码

/******************** (C) COPYRIGHT 2014  **************************************
* Author             : Justchen
* Version            : V1.0
* Date               : 2017.02.07
* Description        : STM32F10X Flash读写API,支持夸页读写,无需字节对齐
********************************************************************************/
#include "stm32f10x.h"

#define MAX_SIZE     40960                              // 定义总共 40K的FLASH做为EEPROM用,必须为PAGE_SIZE的整数倍                        
#define PAGE_SIZE    2048                               // MD器件 1KB为1页   CL与HD为2KB
#define ADDR_OFFSET  (0x8000000+0x40000-MAX_SIZE)       // STM32 flash起始地址+总大小需要写的大小,需要注意的是不同芯片不一样


/**---------------------------------------------------------------------------------
  * @brief  FLASH读出函数
  * @param  地址
  --------------------------------------------------------------------------------*/
u8 FLASH_READ( u32 addr)
{    
    u8  *pointer;
    pointer = (u8*)ADDR_OFFSET;
  return pointer[addr];
}

/**---------------------------------------------------------------------------------
  * @brief  FLASH读出函数
  * @param  地址
  --------------------------------------------------------------------------------*/
void FLASH_READBUFF( u32 addr, u16 num, u8 *data)
{    
    u16 i;

    for( i=0; i<num; i++ )
    {
      data[i] = FLASH_READ(addr+i);
    }
}

/**---------------------------------------------------------------------------------
  * @brief   FLASH写入必不可少步骤
  * @param   地址, 数量, buff
  --------------------------------------------------------------------------------*/
void FLASH_WRITE( u32 addr, u16 num, u8 *data )
{
    u32  pageAddr;
    u8   buff [PAGE_SIZE];
    u8   *pointer;
    u16  i; 
    u16  *p;
    u16  pageWriteLen;
    u16  writeLen;
    u16  totalWriteLen = 0;    

    RCC_HSICmd(ENABLE);
    FLASH_Unlock();
    FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);

    while(1) 
    {
        pageAddr     = ADDR_OFFSET + addr - addr%PAGE_SIZE;     // 页地址        
        pageWriteLen = PAGE_SIZE - addr%PAGE_SIZE;              // 当前页最大可写入字节数

        pointer = (u8*)pageAddr;
        for( i=0; i<PAGE_SIZE; i++)             // 先读出当前页数据保存到buff
            buff[i] = pointer[i];

        if( num > pageWriteLen )                // 计算本次可写入的字节数
            writeLen = pageWriteLen;
        else 
            writeLen = num;        

        for( i=0; i<writeLen; i++)               // 数据先写到buff中
            buff[ (addr%PAGE_SIZE)+i ] = data[totalWriteLen+i];


        FLASH_ErasePage(pageAddr);    // 擦出数据

        p = (u16*)&buff[0];
        for( i=0; i<(PAGE_SIZE/2); i++ )    // 写入数据
            FLASH_ProgramHalfWord( pageAddr + i*2, p[i] );          

        totalWriteLen += writeLen;
        num -= writeLen;
        addr += writeLen;
        if( 0 == num ) break;  // 数据写完 
    }     

    FLASH_Lock(); 
    RCC_HSICmd(DISABLE);        
}

发表评论