STM32F030 HAL库内部 FLASH读写

文章介绍了在STM32F030K6T6微控制器上,由于缺乏EEPROM,作者如何利用内部Flash进行程序自校准。通过读取和写入特定Flash地址来判断和更新校准数据,并在主循环中实现了数据动态调整和更新。在遇到问题时,如地址写入失败,作者进行了调试和调整,确保了功能的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考
https://blog.csdn.net/mrlixirong/article/details/124787282
https://www.163.com/dy/article/GPVKMC5P05458AD7.html

前言

本人使用的是STM32F030K6T6,甲方要求实现程序自校准,第一时间想到eeprom,但发现这块板没有eeprom,改电路又太麻烦,无奈只能摸索内部flash使用。话不多说,直接上代码(结合个人需求,按顺序贴出)。

读flash

float diff=0.00,sum=0.00;
int16_t change_sum = 0;
int16_t change_diff = 0;
//读flash数据,目的是判断是否有数据写入。
HAL_FLASH_Unlock();//解锁
int32_t target_data=0;
target_data=(*(uint32_t *)(0x08007F00));//flag

指针读数,可以直接读32位的,0x08007F00是目标读取的flash地址。
一个小坑,之前只知道flash地址要大于某值(程序本身大小+…),不知道要小于某值(0x08007FFH).
在这里插入图片描述

在这里插入图片描述

写flash

//若有数据写入则从flash中读出已经写入的值,无则将初始值写入flash
if(target_data==0Xffff1111){//read change  有数据写入
		change_diff=(*(uint32_t *)(0x08007F40));
		change_sum=(*(uint32_t *)(0x08007F80));
		printf("target_data1: %x\r\n", target_data);
		printf("change_diff: %f\r\n", (float)change_diff);
		printf("change_sum: %f\r\n", (float)change_sum);
	}
	else{//write  无则将初始值写入flash
		//HAL_FLASHEx_Erase   首先擦除flash(整片)
		FLASH_EraseInitTypeDef EraseInitStruct;
		EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
		EraseInitStruct.PageAddress = 0x08007F00;//目标page所在空间首地址
		EraseInitStruct.NbPages = 1;
		uint32_t PageError=0;
		uint32_t temp=0;
		while(HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
		{
        temp++;
        if(temp>100)
        {
            break;
        }  
		} 
		//write  接着 写flash
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,0x08007F00,0x08007F00,0X1111);//flag
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,0x08007F40,change_diff);//DIFF
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,0x08007F80,change_sum);//SUM
	}

至于为什么判断的值是0Xffff1111,而不是0X1111,直接上测试图吧,具体原因懒得分析了(个人觉得和数据类型有关,change_diff改为int16_t类型就没有前面的ffff了,但页擦除要求32位)。
在这里插入图片描述
还有,之前是想写到0x08007F06和0x08007F10的,失败了,就改为40和80了。

主循环

  while (1)
  {
  		diff= diff+((float)change_diff)*0.3;//校准
  		if(USART_RX_STA&0x8000)
		{		
			if(USART_RX_BUF[0]==0x00  &&USART_RX_BUF[1]==0x00 )//diff--
			{
				change_diff--;
				//HAL_FLASHEx_Erase
				FLASH_EraseInitTypeDef EraseInitStruct;
				EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
				EraseInitStruct.PageAddress = 0x08007F00;
				EraseInitStruct.NbPages = 1;
				uint32_t PageError=0;
				uint32_t temp=0;
				while(HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
				{
       				 temp++;
       				 if(temp>1000UL)
        				{break;}  
				} 
				//write
				HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,0x08007F00,0X1111);//flag
				HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,0x08007F40,change_diff);//DIFF
				HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,0x08007F80,change_sum);//SUM
		
				change_diff=(*(uint32_t *)(0x08007F40));
				change_sum=(*(uint32_t *)(0x08007F80));
				printf("change_diff: %f\r\n", (float)change_diff);
				printf("change_sum: %f\r\n", (float)change_sum);
			}
			
			if(USART_RX_BUF[0]==0x10  &&USART_RX_BUF[1]==0x01 )//show change
			{
				printf("change_diff: %f\r\n", (float)change_diff);
				printf("change_sum: %f\r\n", (float)change_sum);				
			}
		}
  
  }

发送配置图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dawn Yue

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值