OpenEdv-开源电子网

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

有关SPI实验遇到的问题-为什么必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!

[复制链接]

39

主题

597

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
2118
金钱
2118
注册时间
2011-9-3
在线时间
122 小时
发表于 2011-10-9 14:50:54 | 显示全部楼层 |阅读模式

 在SPI实验中,在flash.c中有一句话为“必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!”,不明白为什么要确保所写的地址范围内的数据全部为0XFF,写入的数据才成功?望大家讲解,谢谢。另外如下:有两个SPI写函数,第一个是无检验的,第二个是有检验0XFF的。。


//无检验写SPI FLASH
//必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
//具有自动换页功能
//在指定地址开始写入指定长度的数据,但是要确保地址不越界!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)
//CHECK OK
void SPI_Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)  
{       
 u16 pageremain;   
 pageremain=256-WriteAddr%256; //单页剩余的字节数       
 if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//不大于256个字节
 while(1)
 {   
  SPI_Flash_Write_Page(pBuffer,WriteAddr,pageremain);
  if(NumByteToWrite==pageremain)break;//写入结束了
   else //NumByteToWrite>pageremain
  {
   pBuffer+=pageremain;
   WriteAddr+=pageremain; 

   NumByteToWrite-=pageremain;     //减去已经写入了的字节数
   if(NumByteToWrite>256)pageremain=256; //一次可以写入256个字节
   else pageremain=NumByteToWrite;    //不够256个字节了
  }
 };    
}
//写SPI FLASH 
//在指定地址开始写入指定长度的数据
//该函数带擦除操作!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)      
u8 SPI_FLASH_BUF[4096];          
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)  
{
 u32 secpos;
 u16 secoff;
 u16 secremain;   
  u16 i;   

 secpos=WriteAddr/4096;//扇区地址 0~511 for w25x16
 secoff=WriteAddr%4096;//在扇区内的偏移
 secremain=4096-secoff;//扇区剩余空间大小  

 if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节
 while(1)
 { 
  SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容
  for(i=0;i<secremain;i++)//校验数据
  {
   if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//需要擦除    
  }
  if(i<secremain)//需要擦除
  {
   SPI_Flash_Erase_Sector(secpos);//擦除这个扇区
   for(i=0;i<secremain;i++)    //复制
   {
    SPI_FLASH_BUF[i+secoff]=pBuffer;  
   }
   SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区 

  }else SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间.       
  if(NumByteToWrite==secremain)break;//写入结束了
  else//写入未结束
  {
   secpos++;//扇区地址增1
   secoff=0;//偏移位置为0  

      pBuffer+=secremain;  //指针偏移
   WriteAddr+=secremain;//写地址偏移   
      NumByteToWrite-=secremain;    //字节数递减
   if(NumByteToWrite>4096)secremain=4096; //下一个扇区还是写不完
   else secremain=NumByteToWrite;   //下一个扇区可以写完了
  } 
 };   
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-10-9 15:02:38 | 显示全部楼层
回复【楼主位】螃蟹爱虫:
---------------------------------
建议你了解一下FLASH是怎么样写的。百度啥的都可以了解到吧?flash只能写0,不能写1的。记住这点,你就知道为什么要先是0xff才能写数据了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

39

主题

597

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
2118
金钱
2118
注册时间
2011-9-3
在线时间
122 小时
 楼主| 发表于 2011-10-10 21:45:29 | 显示全部楼层
哦,你的回答让我有针对性的查资料,已明白,谢谢原子哥。。
回复 支持 反对

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2011-10-21
在线时间
0 小时
发表于 2012-3-13 18:39:18 | 显示全部楼层
呵呵,我也在纳闷这个问题,看来原子哥要在以后的版本单独讲讲这个知识点了!!
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2012-3-19
在线时间
0 小时
发表于 2012-3-19 15:45:23 | 显示全部楼层
刚好在这方面遇到困难,学习了!
回复 支持 反对

使用道具 举报

27

主题

62

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2012-7-17
在线时间
0 小时
发表于 2012-8-24 15:46:38 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
想请问原子哥 我也遇到了问题 是不是要首先在所有的地址上都写上OXFF,之后才能写入数据 因为FLASH只能从1写为0  已经是0的无法变成1 ???????/
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2013-8-22
在线时间
0 小时
发表于 2013-8-22 14:25:01 | 显示全部楼层
那为什么页写入时不用检查0XFF呢
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-22 14:26:45 | 显示全部楼层
回复【8楼】jim233:
---------------------------------
何出此言?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

53

主题

175

帖子

1

精华

高级会员

Rank: 4

积分
516
金钱
516
注册时间
2014-5-16
在线时间
7 小时
发表于 2014-7-6 23:19:29 | 显示全部楼层
mark!!
回复 支持 反对

使用道具 举报

7

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2014-11-17
在线时间
0 小时
发表于 2014-11-21 18:25:46 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
 if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//不大于256个字节
原子哥,我感觉这句程序写反了,应该改为if(NumByteToWrite>=pageremain)pageremain=NumByteToWrite;//不大于256个字节
这样才能限制没有出扇区啊
回复 支持 反对

使用道具 举报

7

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2014-11-17
在线时间
0 小时
发表于 2014-11-21 19:05:37 | 显示全部楼层
回复【11楼】1622296203:
---------------------------------
没错,是我搞晕了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-29 04:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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