OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4467|回复: 3

发现FLASH模拟EEPROM实验中例程的错误,导致FLASH写完一页写下一页时无法写入。

[复制链接]

1

主题

4

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2014-7-15
在线时间
0 小时
发表于 2014-7-15 21:15:24 | 显示全部楼层 |阅读模式
我有用FLASH模拟EEPROM时发现FLASH模拟EEPROM实验中例程的错误,导致FLASH写完一页写下一页时无法写入。
当在指定地址写入数据而此时所要写入的数据在本页存不下时就需要写到下一页。
原子哥的例程如下:
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;//非法地址
 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;  
   }
   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();//上锁
}
#endif

程序中如果一个扇区写不完要写到下一个扇区时要将程序的当前写入地址改为入口时赋给程序的WriteAddr加上已经写入的字节数。而secremai是已经写入的半字的个数。所以程序中红色部分应该改为
WriteAddr+=secremain*2; //写地址偏移   
半字个数*2才为字节个数,也就是下一个扇区的地址。如果不乘以2会出现地址不是2的倍数,导致数据无法写入。
个人愚见,请多指教。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-7-15 22:56:02 | 显示全部楼层
这里确实是个bug,已经有网友指出了.
谢谢.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2014-7-15
在线时间
0 小时
 楼主| 发表于 2014-7-16 10:39:59 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
建议这个库函数中存在的bug每隔一段时间整理出来发布一次,大家没事可以去看看把自己原来光盘里拷贴出来的库函数及时更正。
开机后串口发的第一个数出不来这个bug听网友说也是库函数的问题,我到现在还没改呢。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-7-16 23:29:05 | 显示全部楼层
回复【3楼】liushikai:
---------------------------------
恩,不错,谢谢建议.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-5 07:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表