参考
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);
}
}
}
发送配置图