OpenEdv-开源电子网

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

MX25L4006E Flash 写入数据有问题,搞了两三天,还没找到问题所在,那位帮忙看看是什么问题

[复制链接]

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-6-1
在线时间
10 小时
发表于 2015-7-6 21:38:10 | 显示全部楼层 |阅读模式
5金钱
首先说一下使用的是MX25L4006E spi flash芯片
使用的是原子的函数:
void SPI_Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   
{  
u16 pageremain;   
pageremain=SPI_FLASH_PAGESIZE-WriteAddr%SPI_FLASH_PAGESIZE; //单页剩余的字节数    
if(NumByteToWrite<=pageremain)  pageremain=NumByteToWrite;//不大于256个字节
while(1)
{   
SPI_FLASH_Page_Write(pBuffer,WriteAddr,pageremain);
if(NumByteToWrite==pageremain) break;//写入结束了
else //NumByteToWrite>pageremain
{
pBuffer+=pageremain;
WriteAddr+=pageremain;

NumByteToWrite-=pageremain;  //减去已经写入了的字节数
if(NumByteToWrite>SPI_FLASH_PAGESIZE)  pageremain=SPI_FLASH_PAGESIZE; //一次可以写入256个字节
else pageremain=NumByteToWrite;  //不够256个字节了
}
};    


u8 SPI_FLASH_BUF[SPI_FLASH_SECTOR_SIZE]={0};
void SPI_FLASH_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   

u32 secpos;
u16 secoff;
u16 secremain;   
  u16 i;    

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

if(NumByteToWrite<=secremain) secremain=NumByteToWrite;//不大于4096个字节
while(1) 
{
SPI_FLASH_Read(SPI_FLASH_BUF,secpos*SPI_FLASH_SECTOR_SIZE,SPI_FLASH_SECTOR_SIZE);//读出整个扇区的内容
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*SPI_FLASH_SECTOR_SIZE,SPI_FLASH_SECTOR_SIZE);//写入整个扇区 
}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>SPI_FLASH_SECTOR_SIZE) secremain=SPI_FLASH_SECTOR_SIZE; //下一个扇区还是写不完
else secremain=NumByteToWrite; //下一个扇区可以写完了
}  
};  
}
还有就是页编程函数:
void SPI_FLASH_Page_Write(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
  //Enable the write access to the FLASH
  SPI_FLASH_Write_Enable();

  //Select the FLASH: Chip Select low
  SPI_FLASH_CS_LOW();

  //Send "Write to Memory " instruction
  SPI_FLASH_SendByte(MX25L4_PP);

  //Send WriteAddr high nibble address byte to write
  SPI_FLASH_SendByte((u8)((WriteAddr & 0xFF0000) >> 16));

  //Send WriteAddr medium nibble address byte to write
  SPI_FLASH_SendByte((u8)((WriteAddr & 0xFF00) >> 8));

  //Send WriteAddr low nibble address byte to write 
  SPI_FLASH_SendByte((u8)(WriteAddr & 0xFF));
  
while(NumByteToWrite--)
  {
SPI_FLASH_SendByte(*pBuffer);
pBuffer++; 
  }

  //Deselect the FLASH: Chip Select high
  SPI_FLASH_CS_HIGH();

SPI_FLASH_Wait_Busy(); //Waiting for end of writing
}
=====================================================
读取的Flash ID都是正确的,以下是我写入后读出的数据(首先写入的是一个这样的结构体
typedef struct{
unsigned char style;
u8 did;
u16 PulseTab[200];
}IR_Data;  且初始化为0)


这次是写入是正常的,但是下面就是写入256个字节,剩下的数据应该为0才对,为何是65535(即flash初始化的值呢)

请教一下,这是什么原因呢
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-6 22:31:21 | 显示全部楼层
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-6-1
在线时间
10 小时
 楼主| 发表于 2015-7-7 09:37:34 | 显示全部楼层
哦,对了还有一个问题,上面的写函数是带擦除功能,为何我往指定地址写数据(该地址之前是有存在数据),只是单单执行擦除功能而已并没有把数据写进去,难道是我使用的芯片的问题吗?不知道有谁遇到过这种问题没?
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1606
金钱
1606
注册时间
2015-6-10
在线时间
223 小时
发表于 2015-7-7 09:41:08 | 显示全部楼层
flash 初始化是0xff
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-6-1
在线时间
10 小时
 楼主| 发表于 2015-7-7 09:50:57 | 显示全部楼层
回复【4楼】止天:
---------------------------------
你好,我知道初始化是0xFF,但是我使用的那个结构体里面初始化为0的,就算我没有往结构体填数据,那应该写进去也全是0才对呢
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1606
金钱
1606
注册时间
2015-6-10
在线时间
223 小时
发表于 2015-7-7 10:04:53 | 显示全部楼层
你不是只写了256个数吗
为什么剩下的是零啊
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-6-1
在线时间
10 小时
 楼主| 发表于 2015-7-7 10:22:42 | 显示全部楼层
 回复【6楼】 止天 :
---------------------------------
我定义的结构体如下:
typedef struct{
unsigned char style;
u8 did;
u16 PulseTab[200];   400个字节了
}IR_Data;
初始化就全部是0,我要写的是sizeof(IR_Data)=402个字节数呢,只不过里面的数组我写进去就不一定全部写满,所有就会有剩下还是0的原因,怎么会只是是256个字节呢,你看我第一张的图片中的非零数就不只256个了吧,只是我每次写入的数据有时候读出来只是是256个字节(是错误的),有时候又超出256个字节(不过是正常的),这让人费解。
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1606
金钱
1606
注册时间
2015-6-10
在线时间
223 小时
发表于 2015-7-7 10:48:25 | 显示全部楼层
4006每页是256个字节码
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-6-1
在线时间
10 小时
 楼主| 发表于 2015-7-7 11:13:14 | 显示全部楼层
每页多少个字节,还有每个扇区多少个字节我知道,数据手册上也有说明, 我意思是我每次要写入402个字节(已经是多于一页的容量了),有时候是可以正常写入(就是可以写满第一页然后在第二页接着写,类如第一张截图),但有时又只是写入一页数据而已(剩余的65535是SPI Flash初始化的值),感觉已经被截掉一样(如第二张截图)。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-20 22:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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