中级会员
- 积分
- 254
- 金钱
- 254
- 注册时间
- 2022-11-5
- 在线时间
- 28 小时
|
看着正点原子的stm32f103的片上flash代码移植到自己的工程中出错,因为stm32g473的hal库中没有半字写入,所以我把他改成了以双字(64位)的形式写入数据。每次写入一个双字,然后地址增加4,
stm32f103中的宏定义为:
#define FLASH_TYPEPROGRAM_HALFWORD 0x01U /*!<Program a half-word (16-bit) at a specified address.*/
#define FLASH_TYPEPROGRAM_WORD 0x02U /*!<Program a word (32-bit) at a specified address.*/
#define FLASH_TYPEPROGRAM_DOUBLEWORD 0x03U /*!<Program a double word (64-bit) at a specified address*/
stm32g473中为:
#define FLASH_TYPEPROGRAM_DOUBLEWORD 0x00U /*!< Program a double-word (64-bit) at a specified address.*/
#define FLASH_TYPEPROGRAM_FAST 0x01U /*!< Fast program a 32 row double-word (64-bit) at a specified address.
And another 32 row double-word (64-bit) will be programmed */
#define FLASH_TYPEPROGRAM_FAST_AND_LAST 0x02U /*!< Fast program a 32 row double-word (64-bit) at a specified address.
And this is the last 32 row double-word (64-bit) programmed */
下面是我的代码- u16 STMFLASH_ReadHalfWord(u32 faddr)
- {
- return *(vu16 *)faddr;
- }
- #if STM32_FLASH_WREN // 如果使能了写
- // 不检查的写入
- // WriteAddr:起始地址
- // pBuffer:数据指针
- // NumToWrite:半字(16位)数
- // 以**半字(16位)**的形式写入数据。每次写入一个半字,然后地址增加2。这是因为一个半字包含1个16位的数据,所以地址需要增加2。
- // void STMFLASH_Write_NoCheck(u32 WriteAddr, u16 *pBuffer, u16 NumToWrite)
- // {
- // u16 i;
- // for (i = 0; i < NumToWrite; i++)
- // {
- // HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, WriteAddr, pBuffer);
- // WriteAddr += 2; // 地址增加2.
- // }
- // }
- // 以**双字(64位)**的形式写入数据。每次写入一个双字,然后地址增加4。这是因为一个双字包含4个16位的数据,所以地址需要增加4。
- void STMFLASH_Write_NoCheck(u32 WriteAddr, u16 *pBuffer, u16 NumToWrite)
- {
- u16 i;
- u32 buffer;
- for (i = 0; i < NumToWrite; i += 2)
- {
- buffer = ((u32)pBuffer) | ((u32)pBuffer[i + 1] << 16);
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, WriteAddr, buffer);
- WriteAddr += 4; // 地址增加4.
- }
- }
- // 从指定地址开始写入指定长度的数据
- // WriteAddr:起始地址(此地址必须为2的倍数!!)
- // pBuffer:数据指针
- // NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
- #if STM32_FLASH_SIZE < 256
- #define STM_SECTOR_SIZE 1024 // 字节
- #else
- #define STM_SECTOR_SIZE 2048
- #endif
- u16 STMFLASH_BUF[STM_SECTOR_SIZE / 2]; // 最多是2K字节
- void STMFLASH_Write(u32 WriteAddr, u16 *pBuffer, u16 NumToWrite)
- {
- u32 secpos; // 扇区地址
- u16 secoff; // 扇区内偏移地址(16位字计算)
- u16 secremain; // 扇区内剩余地址(16位字计算)
- u16 i;
- u32 offaddr; // 去掉0X08000000后的地址
- if (WriteAddr < STM32_FLASH_BASE || (WriteAddr >= (STM32_FLASH_BASE + 1024 * STM32_FLASH_SIZE)))
- return; // 非法地址
- HAL_FLASH_Unlock(); // 解锁
- offaddr = WriteAddr - STM32_FLASH_BASE; // 实际偏移地址.
- secpos = offaddr / STM_SECTOR_SIZE; // 扇区地址 0~127 for STM32F103RBT6
- secoff = (offaddr % STM_SECTOR_SIZE) / 2; // 在扇区内的偏移(2个字节为基本单位.)
- secremain = STM_SECTOR_SIZE / 2 - secoff; // 扇区剩余空间大小
- if (NumToWrite <= secremain)
- secremain = NumToWrite; // 不大于该扇区范围
- while (1)
- {
- STMFLASH_Read(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE, STMFLASH_BUF, STM_SECTOR_SIZE / 2); // 读出整个扇区的内容
- for (i = 0; i < secremain; i++) // 校验数据
- {
- if (STMFLASH_BUF[secoff + i] != 0XFFFF)
- break; // 需要擦除
- }
- if (i < secremain) // 需要擦除
- {
- FLASH_PageErase(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE, FLASH_BANK_1); // 擦除这个扇区
- FLASH_WaitForLastOperation(FLASH_WAITETIME); // 等待上次操作完成
- CLEAR_BIT(FLASH->CR, FLASH_CR_PER); // 清除CR寄存器的PER位,此操作应该在FLASH_PageErase()中完成!
- // 但是HAL库里面并没有做,应该是HAL库bug!
- for (i = 0; i < secremain; i++) // 复制
- {
- STMFLASH_BUF[i + secoff] = pBuffer;
- }
- STMFLASH_Write_NoCheck(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE, STMFLASH_BUF, STM_SECTOR_SIZE / 2); // 写入整个扇区
- }
- else
- {
- FLASH_WaitForLastOperation(FLASH_WAITETIME); // 等待上次操作完成
- STMFLASH_Write_NoCheck(WriteAddr, pBuffer, secremain); // 写已经擦除了的,直接写入扇区剩余区间.
- }
- if (NumToWrite == secremain)
- break; // 写入结束了
- else // 写入未结束
- {
- secpos++; // 扇区地址增1
- secoff = 0; // 偏移位置为0
- pBuffer += secremain; // 指针偏移
- WriteAddr += secremain * 2; // 写地址偏移(16位数据地址,需要*2)
- NumToWrite -= secremain; // 字节(16位)数递减
- if (NumToWrite > (STM_SECTOR_SIZE / 2))
- secremain = STM_SECTOR_SIZE / 2; // 下一个扇区还是写不完
- else
- secremain = NumToWrite; // 下一个扇区可以写完了
- }
- };
- HAL_FLASH_Lock(); // 上锁
- }
- #endif
- // 从指定地址开始读出指定长度的数据
- // ReadAddr:起始地址
- // pBuffer:数据指针
- // NumToWrite:半字(16位)数
- void STMFLASH_Read(u32 ReadAddr, u16 *pBuffer, u16 NumToRead)
- {
- u16 i;
- for (i = 0; i < NumToRead; i++)
- {
- pBuffer = STMFLASH_ReadHalfWord(ReadAddr); // 读取2个字节.
- ReadAddr += 2; // 偏移2个字节.
- }
- }
复制代码 其中函数STMFLASH_Write_NoCheck被注释的是正点原子的代码,下面是我修改的,现在的问题就是,我测试的时候在地址0X08070000上写入"STM32F103 FLASH TEST",但是读出来的只有STM3,后面的内容都没有了,这是什么问题?求大佬解答
|
|