STM32-OTA(三)读写FLASH

读写FLASH

1. 简述

STM32的写FLASH相对简单,直接读即可,写FLASH相对复杂。首先看STM32的内存大小和分配。

用到的HAL库函数:

HAL_StatusTypeDef HAL_FLASH_Unlock(void);
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError);
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
HAL_StatusTypeDef HAL_FLASH_Lock(void);

2. 读写FLASH代码

#define STM32_FLASH_BASE 0x08000000

/* 获取扇区号 */
static uint8_t bsp_flash_get_sector(uint32_t addr)
{
	if (addr < ADDR_FLASH_SECTOR_1)       return FLASH_SECTOR_0;
	else if (addr < ADDR_FLASH_SECTOR_2)  return FLASH_SECTOR_1;
	else if (addr < ADDR_FLASH_SECTOR_3)  return FLASH_SECTOR_2;
	else if (addr < ADDR_FLASH_SECTOR_4)  return FLASH_SECTOR_3;
	else if (addr < ADDR_FLASH_SECTOR_5)  return FLASH_SECTOR_4;
	else if (addr < ADDR_FLASH_SECTOR_6)  return FLASH_SECTOR_5;
	else if (addr < ADDR_FLASH_SECTOR_7)  return FLASH_SECTOR_6;
	else if (addr < ADDR_FLASH_SECTOR_8)  return FLASH_SECTOR_7;
	else if (addr < ADDR_FLASH_SECTOR_9)  return FLASH_SECTOR_8;
	else if (addr < ADDR_FLASH_SECTOR_10) return FLASH_SECTOR_9;
	else if (addr < ADDR_FLASH_SECTOR_11) return FLASH_SECTOR_10;   
	return FLASH_SECTOR_11;	
}

/* 读FLASH */
uint32_t bsp_flash_read(uint32_t addr)
{
	return *(__IO uint32_t*)(addr);
}

/* 写FLASH */
void bsp_flash_write(uint32_t addr)
{
	FLASH_EraseInitTypeDef f;
	uint32_t sector_error=0;
	uint32_t start_addr = addr;
	uint32_t end_addr = start_addr + (size * 4);
	
	/* 1. 判断地址合法 */
	if ((start_addr < STM32_FLASH_BASE) || (addr % 4)) return;
	
	/* 2. 解锁 */
	HAL_FLASH_Unlock(); 
	
	/* 3. 擦除 */
	if (addr < 0x1FFF0000) 
	{
		while (addr < end_addr) 
		{
			if (hal_flash_read(addr) != 0XFFFFFFFF) 
			{
				f.TypeErase = FLASH_TYPEERASE_SECTORS;
				f.Sector = hal_flash_get_sector(addr);
				f.NbSectors = 1;
				f.VoltageRange = FLASH_VOLTAGE_RANGE_3;
				if (HAL_FLASHEx_Erase(&f, &sector_error)!=HAL_OK) break;
			} 
			else addr += 4;     
			FLASH_WaitForLastOperation(50000);
		}
	}
	
	/* 4. 写入 */
	addr = start_addr;
	while (addr < end_addr) 
	{
		if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, *data) != HAL_OK) break;	
		addr += 4;
		data++;
	}
	
	/* 5. 上锁 */
	HAL_FLASH_Lock();    
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lljwork2021

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

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

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

打赏作者

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

抵扣说明:

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

余额充值