stm32H7 HAL库操作内部Flash BANK2(0x08100000)读写不正常

一、stm32H7 HAL库操作内部Flash BANK2读写不正常

超过1M写道bank2(0x08100000) 后面的内容不正常
HAL_FLASH_Program函数 返回错误 由于用的旧版本HAL库
看到安富莱贴子中关于旧版HAL BUG的问题参考新版HAL做了更改后仍然出现错误 不能正常写
决定采用寄存器方式写 不用HAL库 便将正点原子的寄存器版本中的STMFLASH_Write8Word
底层函数移植过来 问题解决

HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint64_t DataAddress)
{
  HAL_StatusTypeDef status = HAL_ERROR;
  __IO uint64_t *dest_addr = (__IO uint64_t *)FlashAddress;
  __IO uint64_t *src_addr = (__IO uint64_t*)((uint32_t)DataAddress);
  uint32_t bank;
  uint8_t row_index = 4;
  
  /* Process Locked */
  __HAL_LOCK(&pFlash);

  /* Check the parameters */
  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
  assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));

  if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
  {
    bank = FLASH_BANK_1;
  }
  else
  {
    bank = FLASH_BANK_2;    
  }
  
  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
  
  if(status == HAL_OK)
  {
    if(bank == FLASH_BANK_1)
    {
      /* Clear bank 1 pending flags (if any) */ 
      __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1 | FLASH_FLAG_QW_BANK1 | FLASH_FLAG_WBNE_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK1); 
  
      /* Set PG bit */
      SET_BIT(FLASH->CR1, FLASH_CR_PG);
    }
    else
    {
      /* Clear bank 2 pending flags (if any) */ 
      __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2 | FLASH_FLAG_QW_BANK2 | FLASH_FLAG_WBNE_BANK2 | FLASH_FLAG_ALL_ERRORS_BANK2); 
  
      /* Set PG bit */
      SET_BIT(FLASH->CR2, FLASH_CR_PG);  
    }
  
    __ISB();
    __DSB();
    /* Program the 256 bits flash word */
#if 0
    do
    {
      *dest_addr++ = *src_addr++;
    } while (--row_index != 0);
#else
    do
     {
       *dest_addr = *src_addr;
       dest_addr++;
       src_addr++;
       row_index--;
     } while (row_index != 0U);

#endif
    __ISB();
    __DSB();
    
    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
    
    if(bank == FLASH_BANK_1)
    {
      /* Check FLASH End of Operation flag  */
      if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_EOP_BANK1))
      {
        /* Clear FLASH End of Operation pending bit */
        __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
      }
    
      /* If the program operation is completed, disable the PG*/
      CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
    }
    else
    {
      /* Check FLASH End of Operation flag  */
      if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_EOP_BANK2))
      {
        /* Clear FLASH End of Operation pending bit */
        __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
      }
    
      /* If the program operation is completed, disable the PG */
      CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
    }
  }

  /* Process Unlocked */
  __HAL_UNLOCK(&pFlash);

  return status;  
}
u8 STMFLASH_Write8Word(u32 faddr, u32* pdata)
{
	u8 nword=8;	//每次写8个字,256bit
	u8 res;
	u8 bankx=0;
	if(faddr<BANK2_FLASH_SECTOR_0)bankx=0;	//判断地址是在bank0,还是在bank1
	else bankx=1;
	res=STMFLASH_WaitDone(bankx,0XFF);	 
	if(res==0)	//OK
	{
		if(bankx==0)	//BANK1	编程
		{ 
			FLASH->CR1&=~(3<<4);	//PSIZE1[1:0]=0,清除原来的设置 
			FLASH->CR1|=2<<4;		//设置为32bit宽
			FLASH->CR1|=1<<1;		//PG1=1,编程使能 
		}else			//BANK2 编程
		{
			FLASH->CR2&=~(3<<4);	//PSIZE2[1:0]=0,清除原来的设置 
			FLASH->CR2|=2<<4;		//设置为32bit宽
			FLASH->CR2|=1<<1;		//PG2=1,编程使能 
		} 
		while(nword)
		{
			*(vu32*)faddr=*pdata;	//写入数据
			faddr+=4;				//写地址+4
			pdata++;				//偏移到下一个数据首地址
			nword--;
		}
		__DSB();					//写操作完成后,屏蔽数据同步,使CPU重新执行指令序列
		res=STMFLASH_WaitDone(bankx,0XFF);	//等待操作完成,一个字编程,最多100us.

		if(bankx==0)FLASH->CR1&=~(1<<1);//PG1=0,清除扇区擦除标志
		else FLASH->CR2&=~(1<<1);		//PG2=0,清除扇区擦除标志
	} 
	return res;
} 


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32基于HAL库Flash读写操作都是通过HAL库封装的Flash API来实现的。其主要函数包括HAL_FLASH_Unlock、HAL_FLASH_Lock、HAL_FLASH_Program、HAL_FLASH_Erase、HAL_FLASH_GetError等。 1. 解锁Flash操作。在进行Flash操作之前,需要先对Flash进行解锁操作,在操作结束后再进行锁定操作。函数为HAL_FLASH_Unlock()。 2. Flash操作Flash操作可以使用函数: HAL_FLASH_Program(typeDef FlashType, uint32_t Address, uint64_t Data)。FlashType表示数据类型,可以表示不同长度的数据,Address代表入的地址,Data代表要入的数据。 3. 擦除Flash操作。擦除Flash操作可以使用函数: HAL_FLASH_Erase(typeDef CfTypr, uint32_t Address)。CfTypr表示擦除的区域类型,Address表示擦除的起始地址。 4. 锁定Flash操作。在进行Flash操作完毕之后,需要进行一次Flash的锁定操作。函数为HAL_FLASH_Lock()。 5. 错误处理。Flash操作过程中可能因为多种原因出现错误,因此需要使用HAL_FLASH_GetError()函数获取错误代码。 总的来说,STM32基于HAL库Flash读写操作比较简单,可以通过HAL库提供的API来简单实现。在进行操作时,需要注意解锁和锁定Flash操作的顺序以及错误处理。 ### 回答2: STM32基于HAL库flash是一种常见的储存芯片,它可以储存一定量的数据,并且可以重复读写。如果需要在STM32基于HAL库flash读写数据,可以按照以下步骤进行实现: 1. 使能flash 在使用flash前,需要首先使能flash模块。可以使用HAL库提供的函数HAL_FLASH_Unlock()来解锁flash,并使用HAL_FLASH_Lock()来锁定flash。 2. 擦除flash 如果需要对flash进行操作,需要先对flash进行擦除。可以使用HAL库提供的函数HAL_FLASHEx_Erase()对flash进行擦除操作。 3. 入数据 擦除完成后,可以使用HAL库提供的函数HAL_FLASH_Program()来对flash进行操作操作的具体实现需要传入入地址、要入的数据、以及数据长度等参数。 4. 读取数据 读取flash中的数据可以使用HAL库提供的函数HAL_FLASH_Program()来实现。读取操作的具体实现需要传入读取地址、缓冲区、以及数据长度等参数。 总的来说,在STM32基于HAL库flash中进行数据读写较为直接,可以使用HAL库中提供的函数实现。需要注意的是,在读写flash时需要谨慎操作,以免误删数据或对flash芯片造成不必要的损坏。同时,还需要注意read防止读取未入或者已被擦除的数据。这就需要读取数据时,要仔细判断储存数据的地址是否正确,避免出现错误导致数据读取不正确。 ### 回答3: STM32基于HAL库FLASH读写数据可以分为如下几个步骤: 1. 初始化FLASH:使用HAL_FLASH_Unlock()函数将FLASH解锁,在使用FLASH之前需要先解锁,否则FLASH无法操作。然后使用HAL_FLASH_GetError()函数来判断FLASH是否解锁成功。 2. 入数据:使用HAL_FLASH_Program()函数来入数据,参数有三个,第一个是Flash Type,第二个是入的地址,第三个是数据。例如: uint32_t Address = 0x08010000; //入数据的地址,从0x08010000开始 uint32_t Data = 0x12345678; //要入的数据 HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, Data); 在入数据之后,需要判断是否入成功。使用HAL_FLASH_GetError()函数来判断Flash是否入成功。 3. 读取数据:使用指针来读取FLASH中的数据,例如: uint32_t Address = 0x08010000; //读取数据的起始地址 uint32_t DATA = *(__IO uint32_t*)Address; //使用指针读取数据 在读取数据之后,可以将读取到的数据打印在串口终端上,进行测试。 4. 擦除数据:使用HAL_FLASHEx_Erase()函数来擦除Flash中的数据,擦除Flash时,需要注意只能擦除整个扇区,所以需要计算好擦除的扇区大小和起始地址。 例如:擦除从0x08010000开始的一整个Sector: FLASH_EraseInitTypeDef pEraseInit; HAL_FLASH_Unlock(); pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS; pEraseInit.Sector = FLASH_SECTOR_4; pEraseInit.Banks = FLASH_BANK_1; pEraseInit.NbSectors = 1; pEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3; uint32_t SectorError = 0; HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 以上就是STM32基于HAL库FLASH读写数据的基本步骤和详细操作方法。在实际开发中,需要注意的是,每次入和擦除FLASH都需要判断是否操作成功,并且在每次入的时候,需要确保入的地址是合法的,即不会覆盖其他程序或数据,否则会造成程序运行异常。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值