找回密码
 立即注册
查看: 177|回复: 2

求助!关于W25Q128存储器

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:37
  • 最近打卡:2025-05-01 12:11:22
已绑定手机

6

主题

32

回帖

256

积分

中级会员

积分
256
发表于 2025-4-11 12:27:29 | 显示全部楼层 |阅读模式


事情是这样的:
我用W25Q_Write_N这个函数实现把数据放到W25Q128里面,PAGE_SIZE代表每一页256字节大小,为了方便存储和读取,每一页存一条数据就转存到下一页,理论上是可以存65535条数据的,可是每次存到大概249条以后的时候,(test_info.List我把它放在第一页,数据从第二页开始存,每存一条test_info.List++)数据读出来就全是FF,大概看了一下,可能是块的问题,64K为一个块,但是我不能理解为什么往后就存不进去了呢。麻烦大佬们给孩子指点迷津吧


void W25Q_Write_Page(uint8* pbuf,uint32 WriteAddr,uint16 Len)
{
   uint16 i;
   while(W25Q_ReadStatus()&0x01);        //判断是否忙
   WriteEnable();                          //写使能
   SPI_CS_0;                               //使能器件   
   SPI_SendByte(W25X_Writepage);          //发送写页命令
   SPI_SendByte((uint8)((WriteAddr)>>16));   //发送24bit地址   
   SPI_SendByte((uint8)((WriteAddr)>>8));   
   SPI_SendByte((uint8)WriteAddr);  
   for(i=0;i<Len;i++)                      //循环写数
   {
        SPI_SendByte(*pbuf++);      
   }
   SPI_CS_1;                               //取消片选
   while(W25Q_ReadStatus()&0x01);        //等待写入结束   
}


void W25Q_Write_N(uint8 * pbuf,uint32 WriteAddr,uint16 Len)
{
    uint16 PageLen;                  // 页内写入字节长度
    PageLen=256-WriteAddr%256;       // 单页剩余的字节数 (单页剩余空间)
    if(Len<=PageLen) PageLen=Len;    // 不大于256 个字节
    while(1)
    {
        W25Q_Write_Page(pbuf,WriteAddr,PageLen);
        if(PageLen==Len)break;         // 写入结束了
        else
        {
            pbuf+=PageLen;
            WriteAddr+=PageLen;
            Len-=PageLen;              //  减去已经写入了的字节数
            if(Len>256)PageLen=256;    // 一次可以写入256 个字节
            else PageLen=Len;          // 不够256 个字节了
        }
    }
}


W25Q_Write_N(Flash_Save, FLASH_ADDRESS + (test_info.List * PAGE_SIZE), 36);
回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-4-11 12:28:00 | 显示全部楼层
在您的问题中,您提到使用W25Q128存储器时,数据存储到大约249条后,读取的数据全为0xFF。这可能是由于以下几个原因导致的:

1. 块擦除问题:W25Q128的存储结构是以块(Block)为单位进行管理的,每个块大小为64KB。在写入数据之前,必须确保目标块已经被擦除。如果未擦除块,写入操作可能会失败,导致读取时返回0xFF。建议在写入数据前,先检查并擦除目标块。

2. 页边界问题:W25Q128的页大小为256字节。如果写入的数据跨越了页边界,可能会导致数据写入失败。确保每次写入的数据长度不超过页边界,或者在写入时处理页边界问题。

3. 写保护:W25Q128具有写保护功能,如果写保护被启用,写入操作将无法成功。请检查写保护状态,并确保在写入时禁用写保护。

4. 地址计算错误:在您的代码中,地址计算可能存在错误,导致写入地址超出预期范围。请仔细检查地址计算逻辑,确保写入地址正确。

5. 硬件问题:如果以上软件问题都排除了,可能是硬件问题导致的。检查SPI通信是否正常,确保W25Q128与MCU之间的连接稳定。

针对您的问题,建议您按照以下步骤进行排查和解决:

1. 擦除目标块:在写入数据前,先擦除目标块。可以使用W25QEraseSector或W25QEraseBlock函数进行擦除操作。

2. 检查页边界:确保每次写入的数据长度不超过256字节,或者在写入时处理页边界问题。

3. 禁用写保护:在写入数据前,禁用写保护。可以使用W25QWriteDisable函数禁用写保护。

4. 检查地址计算:仔细检查地址计算逻辑,确保写入地址正确。

5. 检查硬件连接:检查SPI通信是否正常,确保W25Q128与MCU之间的连接稳定。

以下是一个示例代码,展示如何在写入数据前擦除块并处理页边界问题:
  1. c
  2. void W25QWritePage(uint8 pbuf, uint32 WriteAddr, uint16 Len) {
  3.     uint16 i;
  4.     uint32 blockAddr = WriteAddr & 0xFFFF0000; // 计算块地址
  5.     // 擦除目标块
  6.     W25QEraseBlock(blockAddr);
  7.     // 写入数据
  8.     while (Len > 0) {
  9.         uint16 writeLen = (Len > 256) ? 256 : Len; // 确保不超过页边界
  10.         while (W25QReadStatus() & 0x01); // 判断是否忙
  11.         WriteEnable(); // 写使能
  12.         SPICS0; // 使能器件
  13.         SPISendByte(W25XWritepage); // 发送写页命令
  14.         SPISendByte((uint8)((WriteAddr) >> 16)); // 发送24bit地址
  15.         SPISendByte((uint8)((WriteAddr) >> 8));
  16.         SPISendByte((uint8)WriteAddr);
  17.         for (i = 0; i < writeLen; i++) {
  18.             SPISendByte(pbuf[i]);
  19.         }
  20.         SPICS1; // 禁用器件
  21.         pbuf += writeLen;
  22.         WriteAddr += writeLen;
  23.         Len -= writeLen;
  24.     }
  25. }
复制代码

通过以上步骤和代码示例,您应该能够解决W25Q128存储器写入数据时遇到的问题。如果问题仍然存在,建议进一步检查硬件和软件配置,或联系技术支持获取帮助。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2025-05-01 09:07:55

717

主题

1万

回帖

1万

积分

管理员

积分
15609
发表于 2025-4-11 12:32:28 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 20:12 , Processed in 0.148216 second(s), 63 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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