Tuesday, November 26, 2013

STM32F103 내부 플래시 메모리 읽기 쓰기 ( Read, write internal flash memory )


// 헤더파일 추가
#include "stm32f10x_flash.h"

// 소스추가  stm32f10x_flash.c



    // 마지막 블럭에 넣는것으로 가정

    // low(LD),medium(MD) density는 블럭이 1KB, High(HD) density는 2KB 단위임.
 

    //HD 이면서 메모리가 512KB 인경우 마지막 블럭은 255번임
    // 어드레스는 0x08000000 + 255* 2048 => 0x0807F800
 
    #define StartAddr ((u32)0x0807F800)
    #define EndAddr ((u32)0x0807F8FF)
 

    //HD 이면서 메모리가 64KB 인경우 마지막 블럭은 255번임
    // 어드레스는 0x08000000 + 63* 2048 => 0x0801F800
 
    #define StartAddr ((u32)0x0801F800)
    #define EndAddr ((u32)0x0801F8FF)
 


    // MD 이면서 메모리가 64KB 인경우 마지막 블럭은 63번임
    // 어드레스는 0x08000000 + 63* 1024 => 0x0800FC00
 
    #define StartAddr ((u32) 0x0800FC00)
    #define EndAddr ((u32) 0x0800FCFF)
 




//구조체 읽기 쓰기:

typedef struct
{
    unsigned char a;
    unsigned char b;
    unsigned char c;

} TEST_STRUCT;




void test_read()
{
 
    // 구조체 읽기:
    TEST_STRUCT t;

    memcpy( &t, (TEST_STRUCT* ) StartAddr, sizeof( t ));
 
    TEST_STRUCT x;
    memcpy( &x, &t, sizeof(t));
 
    // 이제 t.a, t.b, t.c 에 값이 들어있음.
}

void test_write()
{
 
   
    // 구조체 쓰기
    TEST_STRUCT w;
 
    w.a = 1;
    w.b = 2;
    w.c = 3;
   
 
    unsigned int * p_w = (unsigned int *)&w;
    int byte_align  = 0;
    if( (sizeof(w) % 4) > 0)
        byte_align = 1; // 구조체가 32비트단위가 아닌경우 마지막 떨거지들에 대한처리.

    FLASH_Unlock();
    FLASH_ErasePage(StartAddr);

    for( int i=0; i< sizeof( w ) / 4 + byte_align ; i++)
    {
        FLASH_ProgramWord(StartAddr + (i*4) ,  p_w[i]  );
    }
    FLASH_Lock();
   
}


HAL 버전에서는

#include "stm32f1xx_hal_flash.h"

 
    #define StartAddr ((unsigned int)0x0807F800)
    #define EndAddr ((unsigned int)0x0807F8FF)
    HAL_FLASH_Unlock();

    FLASH_PageErase( StartAddr );
    HAL_FLASH_Program( FLASH_TYPEPROGRAM_WORD, StartAddr, 1234);
    HAL_FLASH_Lock();