OpenEdv-开源电子网

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

关于spi中写入数据程序中扇区的一些疑问

[复制链接]

15

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2020-12-19
在线时间
20 小时
发表于 2021-3-9 21:00:07 | 显示全部楼层 |阅读模式
10金钱
原子大哥,刚学习到FLASH的读写这一章,有几个问题,看了两天也没有看明白,如下:
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)  
{
u32 secpos;
u16 secoff;
u16 secremain;   
  u16 i;   
u8 * SPI_FLASH_BUF;  
    SPI_FLASH_BUF=SPI_FLASH_BUFFER;     
  secpos=WriteAddr/4096;//扇区地址
secoff=WriteAddr%4096;//在扇区内的偏移
secremain=4096-secoff;//扇区剩余空间大小  
  //printf("ad:%X,nb:%X\r\n",WriteAddr,NumByteToWrite);//测试用
  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=WriteAddr/4096;//扇区地址
secoff=WriteAddr%4096;//在扇区内的偏移
secremain=4096-secoff;//扇区剩余空间大小   1、这里4096指的是什么,我算了一下,是一个扇区的大小1024*4=4096 对吧。
                                                                   2、我看着主程序调用这个函数的时候,WriteAddr传过来的是地址倒数第100位对吧,不应该按字节处理吗?
                                                                   3、这三个式子又是什么意思
                                                      各位指点一下,能解答哪条都感激不尽


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



最佳答案

查看完整内容[请看2#楼]

讲一下思路吧,其他自己想; W25Qxx 每次擦除至少一个扇区 4096字节,擦除后的状态是 0xFF,写入可以1~256字节写入(256字节为一页); 如果某个地址里面存储了 0xFF,就可以向里面存储任意值,否侧这个地址所在扇区就需要先擦除再写入; 原子例程是1、待写区域 按 扇区边界 分割,即4096的倍数,分割后依次写入; 2、读取扇区4096字节,判断待写入的区域是否 都是 0xFF,如果 都是0xFF 就直接写入,如果 不是 就先擦除再写入 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2017-11-14
在线时间
34 小时
发表于 2021-3-9 21:00:08 | 显示全部楼层
本帖最后由 cjsyrzy 于 2021-3-10 11:28 编辑

讲一下思路吧,其他自己想;
W25Qxx 每次擦除至少一个扇区 4096字节,擦除后的状态是 0xFF,写入可以1~256字节写入(256字节为一页);
如果某个地址里面存储了 0xFF,就可以向里面存储任意值,否侧这个地址所在扇区就需要先擦除再写入;
原子例程是1、待写区域 按 扇区边界 分割,即4096的倍数,分割后依次写入;
2、读取扇区4096字节,判断待写入的区域是否 都是 0xFF,如果 都是0xFF 就直接写入,如果 不是 就先擦除再写入。


回复

使用道具 举报

15

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2020-12-19
在线时间
20 小时
 楼主| 发表于 2021-3-10 21:25:41 | 显示全部楼层
cjsyrzy 发表于 2021-3-10 11:02
讲一下思路吧,其他自己想;
W25Qxx 每次擦除至少一个扇区 4096字节,擦除后的状态是 0xFF,写入可以1~256 ...

我想我应该懂了,secpos=WriteAddr/4096表示这个地址在第几个扇区
secoff=WriteAddr%4096表示所在扇区第几个字节
secremain=4096-secoff表示所在扇区剩下的字节数
然后写入需要判断内部数据是否为0xff, 并且写入的时候按页写入,一页256字节,每个扇区刚好包含16页。判断在第几页或第几页偏移量方法同判断扇区原理一样

看完你的回复,感觉整个程序都能懂了,顺了一遍     感谢大佬
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-10 03:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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