赞
踩
在STM32芯片内部有一个 FLASH 存储器,它主要用于存储代码,我们在电脑上编写好应用程序后,使用下载器把编译后的代码文件烧录到该内部 FLASH 中,由于 FLASH 存储器的内容在掉电后不会丢失,芯片重新上电复位后,内核可从内部 FLASH 中加载代码并运行。
STM32 的内部 FLASH 包含主存储器、系统存储器以及选项字节区域,它们的地址分布及大小见下表:
一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域,它是存储用户应用程序的空间,芯片型号说明中的 256K FLASH、512K FLASH 都是指这个区域的大小。
主存储器分为 256 页,每页大小为 2KB,共 512KB。这个分页的概念,实质就是 FLASH 存储器的扇区,与其它 FLASH 一样,在写入数据前,要先按页(扇区)擦除。
注意上表中的主存储器是本实验板使用的 STM32VET6 型号芯片的参数,即 STM32F1 大容量产品。若使用超大容量、中容量或小容量产品,它们主存储器的页数量、页大小均有不同,使用的时候要注意区分。
主存储器是以页为单位划分的。stm32根据FLASH主存储块容量、页面的不同,系统存储器的不同,分为小容量、中容量、大容量、互联型,共四类产品。
系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、USB 以及 CAN 等 ISP 烧录功能。
选项字节用于配置 FLASH 的读写保护、待机/停机复位、软件/硬件看门狗等功能,这部分共 16 字节。可以通过修改 FLASH 的选项控制寄存器修改。
本工程采用的芯片型号是STM32F103C8T6,CUBEMX的配置按照这个行骗型号进行配置。
#ifndef __FLASH_H__ #define __FLASH_H__ #include "main.h" #include "string.h" #define STM32_FLASH_SIZE 64 //所选STM32的FLASH容量大小(单位为K);本产品选用的型号为:STM32F103C8T6;FALSH大小为64K #if STM32_FLASH_SIZE < 256 #define STM32_SECTOR_SIZE 1024 //一页为1K #else #define STM32_SECTOR_SIZE 2048 //一页为2K #endif #define STM32_FLASH_BASE 0x08000000 //STM32 FLASH起始地址 //写入的FLASH地址,这里为从倒数第一个扇区地址(0x807f800)开始写 //STM32_FLASH_BASE + STM32_SECTOR_SIZE*255 = 0x08000000 + (2048*255) = 0x0807f800 #define FLASH_SAVE_ADDR STM32_FLASH_BASE+STM32_SECTOR_SIZE*255 void FLASH_WriteData(uint32_t FLASH_Addr, uint16_t *FLASH_Data, uint16_t Size); uint16_t FLASH_ReadHalfWord(uint32_t faddr); void FLASH_ReadData(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead); #endif
#include "flash.h" /*从指定地址开始写入数据*/ //FLASH_Addr:起始地址 //FLASH_Data:写入数据指针(写入的数据为16位,至少都要16位) //Size:写入数据长度 void FLASH_WriteData(uint32_t FLASH_Addr, uint16_t *FLASH_Data, uint16_t Size) { /*内部FLASH测试*/ //1.解锁FLASH HAL_FLASH_Unlock(); //2.擦除FALSH //初始化FLASH_EraseInitTypeDef FLASH_EraseInitTypeDef FLASH_Init; FLASH_Init.TypeErase = FLASH_TYPEERASE_PAGES; FLASH_Init.PageAddress = FLASH_Addr; FLASH_Init.NbPages = 1; uint32_t PageError = 0; //3.调用擦除函数 HAL_FLASHEx_Erase(&FLASH_Init,&PageError); //4.对FLASH烧写 uint16_t TempBuf = 0; for(uint16_t i=0;i<Size;i++) { TempBuf = *(FLASH_Data+i); HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,(FLASH_Addr + (i*2)),TempBuf); } //5.锁住FLASH HAL_FLASH_Lock(); } //从指定地址读出数据 //faddr:地址 uint16_t FLASH_ReadHalfWord(uint32_t faddr) { return *(__IO uint16_t*)faddr; } //从指定地址开始读出指定长度的数据 //ReadAddr:起始指针 //pBuffer:数据指针 //NumToRead:大小(至少半字(16位)数) void FLASH_ReadData(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead) { for(uint16_t i=0;i<NumToRead;i++) { pBuffer[i] = FLASH_ReadHalfWord(ReadAddr); ReadAddr+=2; } }
int main(void) { /* USER CODE BEGIN 1 */ char Write_Data[10]="0123456789"; /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ /*将Write_Data数据的内容写进FLASH*/ FLASH_WriteData(FLASH_SAVE_ADDR,(uint16_t *)&Write_Data,10); /*从STM32 FLASH中读出写入的数据,将数据储存在Read_Data中*/ FLASH_ReadData(FLASH_SAVE_ADDR,(uint16_t *)&Read_Data,10); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { printf("FALSH = %s\r\n",Read_Data); HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。