1. 程式人生 > >STM32F0開發筆記9: 微控制器內部Flash的讀寫

STM32F0開發筆記9: 微控制器內部Flash的讀寫

本文介紹應用C語言進行微控制器內部Flash的讀寫技巧,將從檢視文件開始,到最終完成完整的程式。

微控制器型號:STM32F070F6P6

步驟如下:

1、檢視文件《STM32F030x4/x6/x8/xC and STM32F070x6/xB advanced ARM®-based 32-bit MCUs》確認其Flash的內部結構。

2、檢視文件確認STM32F070F6P6內部儲存器地址分配。從下表中得到的主要資訊是Main Flash memory的起始地址是0x08000000,長度是32KB,到0x08017FFF結束(結束值可不關心)。

3、繼續檢視Main Flash memory的內部結構,如下表所示。從此表可以看出其內部Flash按1Kbyte進行分頁,由於STM32F070F6P6為32KB,所以一共分成32頁,分別為Page0-Page31。這個也與Keil的內部設定是相吻合的,見下圖。

4、建立Flash地址列表,加入如下程式,這些程式參照文件自己手動完成,在使用時,儘量靠後使用,以免和自身程式所佔用的Flash空間重疊。

#define ADDR_FLASH_PAGE_0     ((uint32_t)0x08000000) /* Base @ of Page 0, 1 Kbytes */
#define ADDR_FLASH_PAGE_1     ((uint32_t)0x08000400) /* Base @ of Page 1, 1 Kbytes */
#define ADDR_FLASH_PAGE_2     ((uint32_t)0x08000800) /* Base @ of Page 2, 1 Kbytes */
#define ADDR_FLASH_PAGE_3     ((uint32_t)0x08000C00) /* Base @ of Page 3, 1 Kbytes */
#define ADDR_FLASH_PAGE_4     ((uint32_t)0x08001000) /* Base @ of Page 4, 1 Kbytes */
#define ADDR_FLASH_PAGE_5     ((uint32_t)0x08001400) /* Base @ of Page 5, 1 Kbytes */
#define ADDR_FLASH_PAGE_6     ((uint32_t)0x08001800) /* Base @ of Page 6, 1 Kbytes */
#define ADDR_FLASH_PAGE_7     ((uint32_t)0x08001C00) /* Base @ of Page 7, 1 Kbytes */
#define ADDR_FLASH_PAGE_8     ((uint32_t)0x08002000) /* Base @ of Page 8, 1 Kbytes */
#define ADDR_FLASH_PAGE_9     ((uint32_t)0x08002400) /* Base @ of Page 9, 1 Kbytes */
#define ADDR_FLASH_PAGE_10    ((uint32_t)0x08002800) /* Base @ of Page 10, 1 Kbytes */
#define ADDR_FLASH_PAGE_11    ((uint32_t)0x08002C00) /* Base @ of Page 11, 1 Kbytes */
#define ADDR_FLASH_PAGE_12    ((uint32_t)0x08003000) /* Base @ of Page 12, 1 Kbytes */
#define ADDR_FLASH_PAGE_13    ((uint32_t)0x08003400) /* Base @ of Page 13, 1 Kbytes */
#define ADDR_FLASH_PAGE_14    ((uint32_t)0x08003800) /* Base @ of Page 14, 1 Kbytes */
#define ADDR_FLASH_PAGE_15    ((uint32_t)0x08003C00) /* Base @ of Page 15, 1 Kbytes */
#define ADDR_FLASH_PAGE_16    ((uint32_t)0x08004000) /* Base @ of Page 16, 1 Kbytes */
#define ADDR_FLASH_PAGE_17    ((uint32_t)0x08004400) /* Base @ of Page 17, 1 Kbytes */
#define ADDR_FLASH_PAGE_18    ((uint32_t)0x08004800) /* Base @ of Page 18, 1 Kbytes */
#define ADDR_FLASH_PAGE_19    ((uint32_t)0x08004C00) /* Base @ of Page 19, 1 Kbytes */
#define ADDR_FLASH_PAGE_20    ((uint32_t)0x08005000) /* Base @ of Page 20, 1 Kbytes */
#define ADDR_FLASH_PAGE_21    ((uint32_t)0x08005400) /* Base @ of Page 21, 1 Kbytes */
#define ADDR_FLASH_PAGE_22    ((uint32_t)0x08005800) /* Base @ of Page 22, 1 Kbytes */
#define ADDR_FLASH_PAGE_23    ((uint32_t)0x08005C00) /* Base @ of Page 23, 1 Kbytes */
#define ADDR_FLASH_PAGE_24    ((uint32_t)0x08006000) /* Base @ of Page 24, 1 Kbytes */
#define ADDR_FLASH_PAGE_25    ((uint32_t)0x08006400) /* Base @ of Page 25, 1 Kbytes */
#define ADDR_FLASH_PAGE_26    ((uint32_t)0x08006800) /* Base @ of Page 26, 1 Kbytes */
#define ADDR_FLASH_PAGE_27    ((uint32_t)0x08006C00) /* Base @ of Page 27, 1 Kbytes */
#define ADDR_FLASH_PAGE_28    ((uint32_t)0x08007000) /* Base @ of Page 28, 1 Kbytes */
#define ADDR_FLASH_PAGE_29    ((uint32_t)0x08007400) /* Base @ of Page 29, 1 Kbytes */
#define ADDR_FLASH_PAGE_30    ((uint32_t)0x08007800) /* Base @ of Page 30, 1 Kbytes */
#define ADDR_FLASH_PAGE_31    ((uint32_t)0x08007C00) /* Base @ of Page 31, 1 Kbytes */

6、建立CFlash類,程式碼如下:

class CFlash
{
public:
    void UnLockFalsh(void);
    void LockFlash(void);
    boolean ErasePage(uint32_t u32_Page);
    boolean WriteDataToFlash(uint32_t address, uint8_t data3, uint8_t data2, uint8_t data1, uint8_t data0);
    boolean WriteDataToFlash(uint32_t address, uint16_t data1, uint16_t data0);
    boolean WriteDataToFlash(uint32_t address, uint32_t data);
    void ReadDataFromFlash(uint32_t address, uint8_t *data3, uint8_t *data2, uint8_t *data1, uint8_t *data0);
    void ReadDataFromFlash(uint32_t address, uint16_t *data1, uint16_t *data0);
    void ReadDataFromFlash(uint32_t address, uint32_t *data);
};

7、以下是上述成員函式的具體實現,參考使用即可。

#include "include.h"

void CFlash::UnLockFalsh(void)
{
    HAL_FLASH_Unlock();
}

void CFlash::LockFlash(void)
{
    HAL_FLASH_Lock();
}
		
boolean CFlash::ErasePage(uint32_t u32_Page)
{
    FLASH_EraseInitTypeDef EraseInitStruct;
    uint32_t PageError = 0;

    EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.PageAddress = u32_Page;
    EraseInitStruct.NbPages = 1;
	
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
    {
        return TRUE;
    }
    return FALSE;
}

boolean CFlash::WriteDataToFlash(uint32_t address, uint8_t data3, uint8_t data2, uint8_t data1, uint8_t data0)
{
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, (data3 << 24) | (data2 << 16) | (data1 << 8) | data0) != HAL_OK)
    {
        return FALSE;
    }	
    return TRUE;
}

boolean CFlash::WriteDataToFlash(uint32_t address, uint16_t data1, uint16_t data0)
{
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, (data1 << 16) |  data0) != HAL_OK)
    {
        return FALSE;
    }	
    return TRUE;
}

boolean CFlash::WriteDataToFlash(uint32_t address, uint32_t data)
{
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data) != HAL_OK)
    {
        return FALSE;
    }	
    return TRUE;
}


void CFlash::ReadDataFromFlash(uint32_t address, uint8_t *data3, uint8_t *data2, uint8_t *data1, uint8_t *data0)
{
    uint32_t u32_Data;
	
    u32_Data = *(__IO uint32_t *)(address);	
    if (data3 != NULL)
    {
        *data3 = (u32_Data >> 24) & 0xff;
    }
    if (data2 != NULL)
    {
        *data2 = (u32_Data >> 16) & 0xff;
    }
    if (data1 != NULL)
    {
        *data1 = (u32_Data >> 8) & 0xff;
    }
    if (data0 != NULL)
    {
        *data0 = u32_Data & 0xff;
    }
}

void CFlash::ReadDataFromFlash(uint32_t address, uint16_t *data1, uint16_t *data0)
{
    uint32_t u32_Data;
	
    u32_Data = *(__IO uint32_t *)(address);
    *data1 = (u32_Data >> 16) & 0xffff;
    *data0 = u32_Data & 0xffff;
}

void CFlash::ReadDataFromFlash(uint32_t address, uint32_t *data)
{
    *data =  *(__IO uint32_t *)(address);
}

8、到此,就可以直接進行Flash讀寫操作了。

 

原創性文章,轉載請註明出處
CSDN:http://blog.csdn.net/qingwufeiyang12346