138 lines
5.0 KiB
C
138 lines
5.0 KiB
C
/******************** (C) COPYRIGHT 2020 GEEKIMU *******************************
|
||
* File Name : stmflash.c
|
||
* Current Version : V2.0 & ST 3.5.0
|
||
* Author : zhanli 719901725@qq.com & JustFeng.
|
||
* Date of Issued : 2017.1.11 zhanli : Create
|
||
* Comments : STM32 模拟Flash驱动
|
||
********************************************************************************/
|
||
#include "stmflash.h"
|
||
#include "delay.h"
|
||
#include "usart.h"
|
||
#include "stm32f10x_flash.h"
|
||
|
||
#if STM32_FLASH_SIZE<256
|
||
#define STM_SECTOR_SIZE 1024 //字节
|
||
#else
|
||
#define STM_SECTOR_SIZE 2048
|
||
#endif
|
||
|
||
uint16_t STMFLASH_BUF[STM_SECTOR_SIZE / 2];//最多是2K字节
|
||
|
||
/**----------------------------------------------------------------------
|
||
* Function : STMFLASH_ReadHalfWord
|
||
* Description : 读取指定地址的半字(16位数据)
|
||
* Input : faddr:读地址(此地址必须为2的倍数)
|
||
* Output : 对应16位数据
|
||
* Author : zhanli&719901725@qq.com & JustFeng.
|
||
* Date : 2015/10/3 zhanli
|
||
*---------------------------------------------------------------------**/
|
||
uint16_t STMFLASH_ReadHalfWord(uint32_t faddr)
|
||
{
|
||
return *(uint16_t*)faddr;
|
||
}
|
||
|
||
/**----------------------------------------------------------------------
|
||
* Function : STMFLASH_Write_NoCheck
|
||
* Description : 不检查的写入
|
||
* Input : WriteAddr : 起始地址
|
||
pBuffer : 数据指针
|
||
NumToWrite : 半字(16位)数
|
||
* Output : 对应16位数据
|
||
* Author : zhanli&719901725@qq.com & JustFeng.
|
||
* Date : 2015/10/3 zhanli
|
||
*---------------------------------------------------------------------**/
|
||
void STMFLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,
|
||
uint16_t NumToWrite)
|
||
{
|
||
uint16_t i;
|
||
for(i = 0;i < NumToWrite;i++)
|
||
{
|
||
FLASH_ProgramHalfWord(WriteAddr, pBuffer[i]);
|
||
// 地址增加2.
|
||
WriteAddr += 2;
|
||
}
|
||
}
|
||
/**----------------------------------------------------------------------
|
||
* Function : STMFLASH_Write
|
||
* Description : 初始化追踪器的所有校准数据
|
||
* Input : 从指定地址开始写入指定长度的数据
|
||
WriteAddr:起始地址(此地址必须为2的倍数)
|
||
pBuffer:数据指针
|
||
从指定地址开始写入指定长度的数据
|
||
* Author : zhanli&719901725@qq.com & JustFeng.
|
||
* Date : 2015/2/13 zhanli
|
||
*---------------------------------------------------------------------**/
|
||
void STMFLASH_Write(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)
|
||
{
|
||
uint32_t secpos; //扇区地址
|
||
uint16_t secoff; //扇区内偏移地址(16位字计算)
|
||
uint16_t secremain; //扇区内剩余地址(16位字计算)
|
||
uint16_t i;
|
||
uint32_t offaddr; //去掉0X08000000后的地址
|
||
|
||
if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
|
||
|
||
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_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);
|
||
// 复制
|
||
for(i = 0;i < secremain; i++){
|
||
STMFLASH_BUF[i+secoff]=pBuffer[i];
|
||
}
|
||
// 写入整个扇区
|
||
STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);
|
||
}else{
|
||
// 写已经擦除了的,直接写入扇区剩余区间.
|
||
STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);
|
||
}
|
||
|
||
if(NumToWrite == secremain)break;//写入结束了
|
||
else//写入未结束
|
||
{
|
||
secpos++; //扇区地址增1
|
||
secoff = 0; //偏移位置为0
|
||
pBuffer += secremain; //指针偏移
|
||
WriteAddr += secremain; //写地址偏移
|
||
NumToWrite -= secremain; //字节(16位)数递减
|
||
if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2; //下一个扇区还是写不完
|
||
else secremain = NumToWrite; //下一个扇区可以写完了
|
||
}
|
||
};
|
||
FLASH_Lock();//上锁
|
||
}
|
||
/**----------------------------------------------------------------------
|
||
* Function : STMFLASH_Read
|
||
* Description : 从指定地址开始读出指定长度的数据
|
||
ReadAddr:起始地址
|
||
pBuffer : 数据指针
|
||
NumToWrite:半字数
|
||
* Author : zhanli&719901725@qq.com & JustFeng.
|
||
* Date : 2015/2/13 zhanli
|
||
*---------------------------------------------------------------------**/
|
||
void STMFLASH_Read(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead)
|
||
{
|
||
uint16_t i;
|
||
for(i = 0;i < NumToRead; i++){
|
||
// 读取2个字节.
|
||
pBuffer[i] = STMFLASH_ReadHalfWord(ReadAddr);
|
||
// 读取地址偏移2个字节.
|
||
ReadAddr += 2;
|
||
}
|
||
}
|