中级会员
 
- 积分
- 294
- 金钱
- 294
- 注册时间
- 2018-5-3
- 在线时间
- 69 小时
|
1金钱
当下列flash地址有数据时,直接使用EraseFlash函数擦除时正常的。当时flash空间没数据,写入数据,写完擦除第一区域块或者写完第一区域块,擦第二区域的时候么就无法擦除了。
//#define APP_ADDR 0x08003000 //应用程序首地址
//#define PARAM_START_ADDR 0x0800F800 //配置参数存储地址
//#define ABNORMAI_STATE_ADDR 0x0800FC00 //异常状态存储地址
//#define HISTORY_DATA_ADDR 0x0800E800 //履历数据存储地址
//#define HISTORY_DATA_MAXINUM 128 //履历数据单存储区的最大存储字节
//#define HISTORY_DATA_NUM_CUR 37*2 //履历数据单存储区的当前存储数
//共4K的空间,分区两个大区域块,保证擦除时最小可以读到2K的数据。
//以128字节为一个小存储区,共32个小存储区块,保证最小读取数量为16条
//目前通信协议规定履历存储数据为37字数据,共74字节,其余为预留空间。
//当写入第一区域块的最后一个数据时,擦除第二区域块的内容。
//写入时,发现4k空间写满数据,擦除第一区域块内容。/////////当写入第而区域块的最后一个数据时,擦除第一区域块的内容
unsigned short dqwdqd =0;
uint32_t addr1112222=0;
void HisData_Write_flash(uint8_t size)
{
uint8_t i=0; //目前参数区域块的计数,共计128字节
// uint8_t j=0;
uint8_t block_counts=0; //目前将1K的空间分为8块
uint8_t date_flash=0;
uint32_t addr=0;
// EraseFlash(HISTORY_DATA_ADDR,2);
// EraseFlash(0x0800F000,2);
READAGAIN:
date_flash=*(uint8_t*)(HISTORY_DATA_ADDR+block_counts*HISTORY_DATA_MAXINUM+i);
if(date_flash==0xFF)
{
i++;
if(i<=(HISTORY_DATA_MAXINUM-1))
{
goto READAGAIN;
}
else
{
addr=HISTORY_DATA_ADDR+block_counts*HISTORY_DATA_MAXINUM;
addr1112222 = addr;
// if(addr == (HISTORY_DATA_ADDR+0x400+7*128))//写入第一区域块的最后一个存储区的数据,擦除第二存储区
// EraseFlash((HISTORY_DATA_ADDR+0x800),1);
// if(addr == (HISTORY_DATA_ADDR+0x400+7*128))//写入第一区域块的最后一个存储区的数据,擦除第二存储区
if(addr == 0x0800EF80)//写入第一区域块的最后一个存储区的数据,擦除第二存储区
{
//EraseFlash((HISTORY_DATA_ADDR+0x800),2);
EraseFlash(0x0800F000,2);
}
// WriteFlash(¶ms.Rsaddr,addr,size);//设置参数列
WriteFlash(&dqwdqd,addr,sizeof(dqwdqd));//设置参数列
if(addr == HISTORY_DATA_ADDR)//写入第一区域块的最后一个存储区的数据,擦除第二存储区
{
WriteFlash(&dqwdqd,0x0800F000,sizeof(dqwdqd));//设置参数列
}
}
}
else
{
//addr=parameters_start_address+128*j;
block_counts++;
i=0; //需从下去区块重新开始读取
if(block_counts<32)
{
goto READAGAIN; //重新开始下个存储区的读写
}
else
{
//擦除flash 参数区已全部轮询完毕,第一区域块
EraseFlash(HISTORY_DATA_ADDR,2);
block_counts=0;
addr=HISTORY_DATA_ADDR+block_counts*HISTORY_DATA_MAXINUM;
// WriteFlash(¶ms.Rsaddr,HISTORY_DATA_ADDR,size);//设置参数列
dqwdqd ++;
WriteFlash(&dqwdqd,addr,sizeof(dqwdqd));//设置参数列
}
}
}
// 清除Flash
//Address 最好为页的其实地址
//size 擦除size页,不包含本页,1页为1K
void EraseFlash(uint32_t Address,uint8_t size)
{
FLASH_EraseInitTypeDef My_Flash;
uint32_t PageError = 0;
My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
My_Flash.PageAddress = Address; //声明要擦除的地址
My_Flash.NbPages = size;
HAL_FLASH_Unlock(); //解锁FLASH编程擦除控制器
// FLASH->SR = FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPERR;
FLASH->SR = FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPERR;
HAL_FLASHEx_Erase(&My_Flash, &PageError);
// FLASH->SR = FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPERR;
FLASH->SR = FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPERR;
HAL_FLASH_Lock(); //锁定FLASH编程擦除控制器
}
//Data 为16位数据
//Address 写入的起始地址
//len 写入n个字节
void WriteFlash(uint16_t *Data,uint32_t Address, int len)
{
uint8_t i = 0;
uint16_t data_flash;
len=len/2;
HAL_FLASH_Unlock(); //解锁FLASH编程擦除控制器
// FLASH->SR = FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPERR;
FLASH->SR = FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPERR;
while(i < len)
{
//Data[i]为0x1234,写入的为12 34
data_flash = (Data[i]>>8)+ (((uint8_t)Data[i])<<8);
FLASH_Program_HalfWord(Address, data_flash);
i=i+1;
Address = Address+2;
}
// FLASH->SR = FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPERR;
FLASH->SR = FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPERR;
HAL_FLASH_Lock(); //锁定FLASH编程擦除控制器
}
|
-
|