单片机型号:STM32F070F6P6
本文介绍应用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。