FLASH写入、读取

#ifndef  FLASH_H
#define  FLASH_H
#include "main.h"

#ifdef   FLASH_C
#include "stm32f10x_flash.h"

void FLASH_Erase(uint Addr);

#endif

#define FLASH_BasePos 0x08000000

/*low-density devices*/
//#define FLASH_PAGE1024
//#define FLASH_EndPos  0x08004000        //x4
//#define FLASH_EndPos  0x08008000        //x6

//#define FLASH_SecSize 0x00000400

/*medium-density devices*/
//#define FLASH_PAGE1024
//#define FLASH_EndPos  0x08010000        //x8
//#define FLASH_EndPos  0x08020000        //xB

//#define FLASH_SecSize 0x00000400

/*high-density devices*/
#define FLASH_PAGE2048
#define FLASH_EndPos  0x08040000        //xC
//#define FLASH_EndPos  0x08060000        //xD
//#define FLASH_EndPos  0x08080000        //xE

#define FLASH_SecSize 0x00000800

typedef struct{
    ushort  Page;
    ushort* Data;
    ushort  Length;
    uint    WriteAddr;
    uchar   Flag;
} FLASH_PageTypeDef;

ushort FLASH_Read(uint Addr);

void FLASH_WriteNoCheck(uint Addr, ushort Data);
void FLASH_WriteCheck  (uint Addr, ushort* Data, ushort Length);

void  FLASH_PageCopy (uint f_Addr, uint t_Addr);
void  FLASH_PageWrite(FLASH_PageTypeDef* Page);
uchar FLASH_PageRead (FLASH_PageTypeDef* Page);

#endif
#define  FLASH_C
#include "flash.h"
ushort SecBuf[FLASH_SecSize >> 1];

void FLASH_WriteNoCheck(uint Addr, ushort Data)
{
    if(Addr < FLASH_BasePos || Addr >= FLASH_EndPos || Addr & 0x00000001)
    {
        return;
    }

    FLASH_Unlock();
    
    FLASH_ProgramHalfWord(Addr, Data);

    FLASH_Lock();
}

void FLASH_WriteCheck(uint Addr, ushort* Data, ushort Length)
{
    if(Addr < FLASH_BasePos || Addr >= FLASH_EndPos || Addr & 0x00000001)
    {
        return;
    }

    uint SecNum = (Addr - FLASH_BasePos) / FLASH_SecSize;
    uint SecPos = (Addr - FLASH_BasePos) % FLASH_SecSize;
    uint SecHed = SecNum * FLASH_SecSize + FLASH_BasePos;

    if(SecPos + (Length << 1) > FLASH_SecSize)
    {
        ushort ThisPage_Length = (FLASH_SecSize - SecPos) >> 1;
        ushort NextPage_Length = Length - ThisPage_Length;

        FLASH_WriteCheck(SecHed + FLASH_SecSize, Data + ThisPage_Length, NextPage_Length);

        Length = ThisPage_Length;
    }

    for(ushort i = 0; i < SecPos; i += 2)
    {
        SecBuf[i >> 1] = FLASH_Read(SecHed + i);
    }
    
    ushort SecHalfPos = SecPos >> 1;
    for(ushort i = 0; i < Length; i ++)
    {
        SecBuf[SecHalfPos + i] = Data[i];
    }
    
    for(ushort i = SecPos + (Length << 1); i < FLASH_SecSize; i += 2)
    {
        SecBuf[i >> 1] = FLASH_Read(SecHed + i);
    }

    FLASH_Unlock();

    FLASH_ErasePage(SecHed);

    ushort Write_Data;
    for(ushort i = 0; i < FLASH_SecSize; i += 2)
    {
        Write_Data = SecBuf[i >> 1];
        if(Write_Data == 0xFFFF) continue;
        else FLASH_WriteNoCheck(SecHed + i, Write_Data);
    }

    FLASH_Lock();
}

void FLASH_PageCopy(uint f_Addr, uint t_Addr)
{
    ushort SecHalfSize = FLASH_SecSize >> 1;
    
    for(ushort i = 0; i < SecHalfSize; i ++)
    {
        SecBuf[i] = FLASH_Read(f_Addr + (i << 1));
    }
    
    FLASH_Unlock();

    FLASH_ErasePage(t_Addr);
    
    for(ushort i = 0; i < SecHalfSize; i ++)
    {
        if(SecBuf[i] == 0xFFFF) continue;
        else FLASH_WriteNoCheck(t_Addr + (i << 1), SecBuf[i]);
    }
    
    FLASH_Lock();
}

void FLASH_Erase(uint Addr)
{
    FLASH_Unlock();
    FLASH_ErasePage(Addr);
    FLASH_Lock();
}

void FLASH_PageWrite(FLASH_PageTypeDef* Page)
{
    if(!Page->Flag) return;
    
    for(ushort i = 0; i < Page->Length; i ++)
    {
        FLASH_WriteNoCheck(Page->WriteAddr + (i << 1), Page->Data[i]);
    }
    Page->Flag = 0;
}

uchar FLASH_PageRead(FLASH_PageTypeDef* Page)
{
    uint HeadAddr = FLASH_BasePos + (Page->Page * FLASH_SecSize);
    uint TailAddr = HeadAddr + FLASH_SecSize;

    uint CurrAddr;
    for(CurrAddr = HeadAddr; CurrAddr < TailAddr; CurrAddr += Page->Length)
    {
        uchar Flag = 1;
        for(ushort i = 0; i < Page->Length && CurrAddr + (i << 1) < TailAddr; i ++)
        {
            if(FLASH_Read(CurrAddr + (i << 1)) != 0xFFFF)
            {
                Flag = 0;
                break;
            }
        }
        
        if(Flag)
        {
            break;
        }
    }

    if(CurrAddr == HeadAddr)
    {
        Page->WriteAddr = HeadAddr;
        Page->Flag = 1;
        return 1;
    }

    for(ushort i = 0; i < Page->Length; i ++)
    {
        Page->Data[i] = FLASH_Read(CurrAddr - ((Page->Length - i) << 1));
    }

    if(CurrAddr + (Page->Length << 1) > TailAddr)
    {
        Page->WriteAddr = HeadAddr;
        FLASH_Erase(HeadAddr);
    }
    else
    {
        Page->WriteAddr = CurrAddr;
    }
    
    Page->Flag = 1;
    return 0;
}

ushort FLASH_Read(uint Addr)
{
    return *(vu16*)Addr;
}

 

posted on 2020-10-13 21:02  棕色的北极熊  阅读(552)  评论(0)    收藏  举报