OpenEdv-开源电子网

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

用W25Q64BV的FLASH存储,为啥换页的时候存不上呢?

[复制链接]

7

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2013-5-12
在线时间
0 小时
发表于 2013-7-27 12:37:10 | 显示全部楼层 |阅读模式
我想用外接的一个FLASH进行存储,例如把一串字条存到W25Q64BV里,然后再读取出来在TFT上显示存的内容。但是在存储的过程中会出现如下的现象:
比如我从第0个BLOCK的第0个扇区中进行存储,地址是0xfe ;存的内容是STM32。由于存的字符数大于2个字节就要换页了,当读取的时候,大于2个字节的部分可以读出来,而前两个字节根本没有存进去。这是怎么回事啊?为什么换页以后,之前页的内容没有存进去呢?研究了好久也不知道。

u8 Buffer[] = {"STM32"};
#define size sizeof(Buffer)
/*****另一个源文件的函数*******/

u8 SPI_Write_Page(u8 *string,u32 WriteToAddr,u32 Bytes)
{
u32 PagePos,PagePosRemain,i;
PagePos = WriteToAddr%256;   //要写入页的起始地址
PagePosRemain = 256 - PagePos;//该页中剩余的空间
if(Bytes <= PagePosRemain)
{
PagePosRemain = Bytes;
}
SPI_Write_ENABLE();
SPI_Status();
Flash_CS_ENABLE();
SPI_Send(0x02);
SPI_Send((u8)(WriteToAddr >> 16));
SPI_Send((u8)(WriteToAddr >> 8));
SPI_Send((u8)WriteToAddr);

for(i = 0; i < PagePosRemain; i++)
{
SPI_Send(string);
}
Flash_CS_DISABLE();
SPI_Status();
if((Bytes - PagePosRemain) > 0)
{
return 0; //一页不够
}
else 
{
return 1; //一页够了
}
}


u8 BufferSize[4096],finish_flag;
void SPI_Write_FLASH(u8 *string,u32 WriteToAddr,u32 Bytes)
{
u8 secpos,secpos_temp,eraser_flag = 0;
u16 sec_offset;
u16 sec_remain;
secpos = WriteToAddr / 4096;
sec_offset = WriteToAddr % 4096;
sec_remain = 4096 - sec_offset;

if(Bytes <= sec_remain)
{
sec_remain = Bytes;
}
while(1)
{
u32 i;
SPI_Read_sector(BufferSize,secpos*4096,4096);
  for(i = 0; i < sec_remain; i++)
{
if(BufferSize[sec_offset + i] != 0xff)
{
eraser_flag = 1;
break;
}
else
{
eraser_flag = 0;
}
}
   if(eraser_flag == 1)   //如果eraser_flag == 1就要擦除该扇区
{
SPI_Eraser_Flash(secpos);
continue;
}
else if(eraser_flag == 0)    //如果eraser_flag == 0,说明扇为空,可以定入内容
{
finish_flag = SPI_Write_Page(string,WriteToAddr,Bytes);  //向页中写入内容
}
if(finish_flag)  //如果为1,不用换页,直接跳出主循环
{
break;
}
while(!finish_flag)  //如果为0,说明一页写完以后,要存的内容没写完,继续写
{
string += 256 - WriteToAddr%256;  //指针指向没写入FLASH的剩余内容的起始地址
Bytes -= 256 - WriteToAddr%256;  //剩余字节数
WriteToAddr += 256 - WriteToAddr%256; //开始写剩余字节在FLASH中的起始地址

secpos_temp = WriteToAddr / 4096;
if(secpos_temp == secpos)  //如果没换扇区
{
finish_flag = SPI_Write_Page(string,WriteToAddr,Bytes); //再写剩余的内容
}
else
{
secpos++;
sec_offset = WriteToAddr % 4096;
sec_remain = 4096 - WriteToAddr % 4096;
break;
}
}
}
}


/******main文件********/
……
……
int main()
{
……
……
for( ; ; )
{
if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_4) == RESET)
        {
                 ……


                SPI_Write_FLASH(Buffer,0xfe,size);


                …… 
        }
        if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_5) == RESET)
        {
                ……


                SPI_Read_sector(data,0xfe,size);


                ……
        }
}
}


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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-27 14:11:55 | 显示全部楼层
回复【楼主位】小馒头LZ:
---------------------------------
你这代码,没时间帮你分析.
你可以参考下我们的spi flash例子.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

7

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2013-5-12
在线时间
0 小时
 楼主| 发表于 2013-7-27 14:21:37 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
您提供的例程我看了,写入的地址是从1000(0X3E8)开始写入,而要放入的字符是"MiniSTM32 SPI TEST",这些字符大小总共为13个字符。而起始地址1000到该页结束可以存放24个字符,也就是说不涉及到换页的操作。假如我从一页的最后一个地址开始存放,但是要放入的字节数大于2的时候,需要换页操作,但是不知道怎么换啊?
回复 支持 反对

使用道具 举报

7

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2013-5-12
在线时间
0 小时
 楼主| 发表于 2013-7-27 14:30:42 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
还有就是,如果从一页的最后一个地址开始存储,然后地址加1,然后算出下一页的起始地址后再写里写入完成时,上一页最后一个地址内为空,数据没写进去。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-27 15:38:35 | 显示全部楼层
回复【4楼】小馒头LZ:
---------------------------------
我们的例程直接调动就是了,换页什么的我帮你设计好了都.
直接调用我们的函数就是了.你想在任何地址,写入任何长度的数据,都是可以的.只要地址没超过q64的范围即可.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2013-5-12
在线时间
0 小时
 楼主| 发表于 2013-7-27 23:02:15 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
谢谢原子哥,您提供的例程好用。但我就是不明白自己写的那个到底错在哪里。呵呵
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-16 10:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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