学习日记——单片机内部flash读写(2020.2.12)

FLASH基础知识

• stm32的flash地址起始于0x0800 0000,结束地址 是0x0800 0000加上芯片实际的flash大小,不同 的芯片flash大小不同。
• Flash中的内容一般用来存储代码和一些定义为 const的数据,断电不丢失。
• 内部Flash的构成:
• STM32 的内部 FLASH 包含主存储器、系统存储器、 OTP 区域以及选项字节区域。

内部FLASH的构成

• STM32 的内部 FLASH 包含主存储器、系统存储器、 OTP 区域以及选项字节区域。
• 主存储器:一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域它是 存储用户应用程序的空间,芯片型号说明中的 1M FLASH、 2M FLASH 都是指这个 区域的大小。与其它 FLASH 一样,在写入数据前,要先按扇区擦除。
• 系统存储区:系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动 代码,它负责实现串口、 USB 以及 CAN 等 ISP 烧录功能。
• OTP 区域:OTP(One Time Program),指的是只能写入一次的存储区域,容量为 512 字节,写入后数据就无法再更改, OTP 常用于存储应用程序的加密密钥。
• 选项字节:选项字节用于配置 FLASH 的读写保护、电源管理中的 BOR 级别、软件 /硬件看门狗等功能,这部分共 32 字节。可以通过修改 FLASH 的选项控制寄存器 修改。

配置引脚

配置LED,KEY1,KEY2和串口
在这里插入图片描述

配置系统时钟

采用内部时钟(默认);配置系统时钟最高80MHZ
在这里插入图片描述

配置引脚详细参数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

生产FLASH工程

1、自定义工程名称。
2、选择英文路径,否则会丢 失启动文件而无法编译通过, 需要手动添加启动文件: startup_stm32l431xx.s
3、选择MDK-ARM V5开发软件, 即KEIL5软件

代码编写说明

1、按键KEY1按下时,把数据写入MCU的flash
2、按键KEY2按下时,把写入MCU的flash数据并读取出来,打印数据。
调用函数
1、HAL_FLASH_Unlock(void);//解锁
2、FLASH_EraseInitTypeDef FLASH_EraseInitSturcture;//配置需要擦除的参数
3、HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef pEraseInit, uint32_tPageError);//擦除
4、HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);//写数据到flash
5、HAL_FLASH_Lock(void);//锁住
6、HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//检测按键
7、void HAL_Delay(uint32_t Delay);//延时
8、HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//点亮和熄灭LED
9、uint8_t OneWord=(__IO uint32_t)addr;//读取地址数据
10、printf();//打印数据到串口函数 需要重新定义函数fputc();才能正常使用printf();
int fputc(int ch,FILE*f)
{
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,2);
return HAL_OK;
}

代码编写说明

• FLASH读写流程
1、对FLASH写入数据流程:
1)解锁FLASH:调用HAL_FLASH_Unlock(void);
2)擦除FLASH:调用HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef pEraseInit, uint32_t PageError);
3)写入数据到FLASH:调用HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
4)锁住FLASH:调用HAL_FLASH_Lock(void);
2、FLASH读取数据流程 直接读取相应的FLASH地址即可:通过
(__IO uint32_t
)ADDR读取该地址数据

代码编写实现

#define strLen sizeof(strWriteToFlash1)/sizeof(uint8_t) //写入数据的长度
#define ADDR 0x0803f800 //写地址
写入FLASH数据

void writeflash(int addr, uint32_t* writeFlashData) 
{ 
	uint32_t PageError = 0; 
	int i=0; HAL_FLASH_Unlock();
	FLASH_EraseInitTypeDef f; 
	f.Banks=1; 
	f.NbPages=1; 
	f.Page=255; 
	f.TypeErase=0;
	HAL_FLASHEx_Erase(&f,&PageError);
	HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,addr,writeFlashData[i]); 
	HAL_FLASH_Lock(); 
}

代码编写实现

while(1)循环内程序

if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==GPIO_PIN_RESET)
 { 
 	HAL_Delay(100); 
 	if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==GPIO_PIN_RESET)
 	 {
 	 printf("KEY1 Press\r\n");
 	 writeflash(ADDR,(uint32_t*)&writeFlashData);//擦除并写入数据			        HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);//LED电平翻转
 	  } 
 }
 if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==GPIO_PIN_RESET) 
 {
 	HAL_Delay(100);
 	if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==GPIO_PIN_RESET)
 	{
 		printf("KEY2 Press\r\n"); ReadFlashData(ADDR,sizeof(writeFlashData),R_OldFlash);//读取写入的数据 
 		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin); //LED电平翻转 }}
 		```
 **读取FLASH数据**: 
 `void ReadFlashData(int addr,uint32_t strSize,uint8_t* ReadData) 
 {
 	uint8_t OneWord; for(int i=0;i<strSize;i++)
 	 {
 	 	OneWord=*(__IO uint32_t*)addr; 
 	 	ReadData[i]=OneWord; 
 	 	addr++;
 	  }
 	  	printf("Read the flash data:>>%s<<,address:%x\r\n",ReadData,addr-strSize);// 显示该地址的数据 
 }`
 **扩展实验**:将移植flash.c,该文件有实现写数 据到FLASH的多种方式,如写字符串数据到 FLASH等。



 




发布了9 篇原创文章 · 获赞 0 · 访问量 258

猜你喜欢

转载自blog.csdn.net/quanqueen/article/details/104331534