OpenEdv-开源电子网

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

求助关于W25Q128的读写问题。

[复制链接]

22

主题

133

帖子

2

精华

高级会员

Rank: 4

积分
901
金钱
901
注册时间
2015-12-24
在线时间
197 小时
发表于 2016-11-2 13:00:41 | 显示全部楼层 |阅读模式
3金钱
背景:
    我要做一个记录器,使用片外W25Q128做数据存储,设计是这样的,系统参数保存在一个大小为32Byte的结构体中,每个扇区可以存128次,存满清空,读取时读取最后一次保存的值,此功能目前已经实现,参数保存在0x000000-0x000FFF的扇区中。
    另外,要存储若干条数据,每条数据的结构体大小为16字节,每扇区存储256条,目前使用0x002000-0x016000存储,共20扇区,计5120条数据,使用循环队列式的结构,写满后擦除下一个扇区继续写入,至最后一个扇区时返回头部。
问题:
    不知道写入失败还是读取失败,独处的数据记录全是0xFF,代码用的是原子战舰开发板的示例代码。

源代码如下,请大家指正:
    读取系统设置参数(成功)
void GLB_ReadSystemParameter(void)
{
        uint32_t                        uiDataIndex = 0;
        GLB_SYSPARAMETER        stSystemParameterRead;
        uint32_t                        uiAddress;
        GLB_DATAITEM                stDataItemDataCmp = {0x00};
#ifdef        DBG_OUT
        RTC_CALENDAR_STRUCT        stDBGCleandar;
#endif
        // Read system parameter.
        while(uiDataIndex < 128)
        {
                uiAddress = SYSCFG_ADDRESS + (uiDataIndex * sizeof(GLB_SYSPARAMETER));
                FLASH_ReadArray((uint8_t*)(&stSystemParameterRead), uiAddress, sizeof(GLB_SYSPARAMETER));
               
                if(stSystemParameterRead.Index == 0xFFFFFFFF)
                {
                        if(uiDataIndex == 0)
                        {
                                // No parameter set, load default value.
                                stSystemParameterRead.Index = 1;
                                stSystemParameterRead.FirstSectorIndex = (DATA_SECTOR_NUMBER - 1);                                                        //First index is 0;
                                stSystemParameterRead.LastSectorIndex = 0;        //Set start sector index is last sector.
                                stSystemParameterRead.DataCursor = 0;                                                               
                                stSystemParameterRead.Magnification = 1.0;
                                stSystemParameterRead.SaveTime = 2;
                                memcpy(&gstSystemParameter, &stSystemParameterRead, sizeof(gstSystemParameter));
                                break;
                        }
                        else
                        {
                                // Read invalid parameter data, save last read.
                                break;
                        }
                }
                else
                {
                        // Copy currant data to global parameter data.
                        memcpy(&gstSystemParameter, &stSystemParameterRead, sizeof(gstSystemParameter));
                        uiDataIndex ++;
                }
        }
#ifdef        DBG_OUT
        printf("Read parameter...\r\n");
        printf("    Index: %u.\r\n", gstSystemParameter.Index);
        printf("    SaveTime: %2u.\r\n", gstSystemParameter.SaveTime);
        printf("    FirstSectorIndex: %u\r\n", gstSystemParameter.FirstSectorIndex);
        printf("    LastSectorIndex: %u\r\n", gstSystemParameter.LastSectorIndex);
        printf("    LastDataInSector: %u\r\n", gstSystemParameter.DataCursor);
#endif
        // Read Last counter.
        printf("Read data record...\r\n");
        uiAddress = DATA_START_ADDRESS + (gstSystemParameter.LastSectorIndex*4096) + (gstSystemParameter.DataCursor * sizeof(GLB_DATAITEM));
        FLASH_ReadArray((uint8_t*)(&stDataItemDataCmp), uiAddress, sizeof(GLB_DATAITEM));
        if(stDataItemDataCmp.Index == 0xFFFFFFFF)
        {
                printf("Invalid data record.\r\n");
                guiCounter = 0;
        }
        else
        {
#ifdef        DBG_OUT
                printf("    Index: %u.\r\n", stDataItemDataCmp.Index);
                memcpy(&stDBGCleandar, RTC_ConvertToCalendar(stDataItemDataCmp.TimeStamp), sizeof(RTC_CALENDAR_STRUCT));
                printf("    Time: %04u-%02u-%02u %02u:%02u:%02u.\r\n", stDBGCleandar.tm_year, stDBGCleandar.tm_mon, stDBGCleandar.tm_mday, stDBGCleandar.tm_hour, stDBGCleandar.tm_min, stDBGCleandar.tm_sec);
                printf("    Value: %8.2f\r\n", stDataItemDataCmp.Value);
#endif
                // Recover records.
                guiCounter = stDataItemDataCmp.Value;
                memcpy(&gstDataItemData, &stDataItemDataCmp, sizeof(GLB_DATAITEM));
        }
}


    保存系统设置参数(成功)
void GLB_SaveSystemParameter(void)
{
        uint32_t                        uiDataIndex = 0;
        uint32_t                        uiAddress;
        GLB_SYSPARAMETER        stSystemParameterRead;
       
        while(1)
        {
                uiAddress = SYSCFG_ADDRESS + (uiDataIndex * sizeof(GLB_SYSPARAMETER));
                FLASH_ReadArray((uint8_t*)(&stSystemParameterRead), uiAddress, sizeof(gstSystemParameter));
                if(stSystemParameterRead.Index == 0xFFFFFFFF)
                {
                        if(uiDataIndex < 128)
                        {
                                // System parameter area is not  full.
                                gstSystemParameter.Index ++;
                                FLASH_WriteArray((uint8_t*)(&gstSystemParameter), uiAddress, sizeof(gstSystemParameter));
                        }
                        else
                        {
                                // System parameter area is full, clear before rewrite.
                                printf("System parameter area is full, clear and rewrite.\r\n");
                                FLASH_EraseSector(SYSCFG_ADDRESS / 4096);
                                gstSystemParameter.Index = 1;
                                FLASH_WriteArray((uint8_t*)(&gstSystemParameter), SYSCFG_ADDRESS, sizeof(gstSystemParameter));
                        }
                        break;
                }
                else
                {
                        uiDataIndex ++;
                }
        }
#ifdef        DBG_OUT
        printf("Write parameter to address 0x%08X\r\n", uiAddress);
        printf("    Index: %u.\r\n", gstSystemParameter.Index);
        printf("    SaveTime: %2u.\r\n", gstSystemParameter.SaveTime);
        printf("    FirstSectorIndex: %u\r\n", gstSystemParameter.FirstSectorIndex);
        printf("    LastSectorIndex: %u\r\n", gstSystemParameter.LastSectorIndex);
        printf("    LastDataInSector: %u\r\n", gstSystemParameter.DataCursor);
#endif
}


保存数据函数(有问题)
void GLB_SaveDataItem(GLB_DATAITEM* pData)
{
        uint32_t        uiDataAddress;
#ifdef        DBG_OUT
        RTC_CALENDAR_STRUCT        stDBGCleandar;
        GLB_DATAITEM                stDataItemDataCmp = {0x00};
#endif
        // Update data cursor.
        gstSystemParameter.DataCursor ++;
        if(gstSystemParameter.DataCursor < (4096 / sizeof(GLB_DATAITEM)))
        {
                // Data address is in current sector.
        }
        else
        {
                // Current sector is full, turn to next sector.
                gstSystemParameter.LastSectorIndex ++;
                gstSystemParameter.LastSectorIndex %= DATA_SECTOR_NUMBER;
                gstSystemParameter.DataCursor = 0;
        }
        // Check current sector is full.
        if(gstSystemParameter.LastSectorIndex == gstSystemParameter.FirstSectorIndex)
        {
                printf("Current data sector(%d) is full.\r\n", gstSystemParameter.LastSectorIndex);
                // First sector turn to next.
                gstSystemParameter.FirstSectorIndex ++;
                gstSystemParameter.FirstSectorIndex %= DATA_SECTOR_NUMBER;
                // Erase current sector.
                FLASH_EraseSector((DATA_START_ADDRESS / 4096) + gstSystemParameter.LastSectorIndex);
        }
        // Get save address.
        uiDataAddress = DATA_START_ADDRESS+(gstSystemParameter.LastSectorIndex*4096)+(gstSystemParameter.DataCursor * sizeof(GLB_DATAITEM));
        // Update index.
        gstDataItemData.Index ++;
        // Update Now time.
        gstDataItemData.TimeStamp = RTC_GetNowTimeStamp();
        // Write to data area;
        FLASH_WriteArray((uint8_t*)pData, uiDataAddress, sizeof(GLB_DATAITEM));
#ifdef        DBG_OUT
        // DBG log.
        printf("Write data to address %u(0x%08X).\r\n", uiDataAddress, uiDataAddress);
        printf("    Index: %u, Value: %8.2f.\r\n", pData->Index, pData->Value);
        memcpy(&stDBGCleandar, RTC_ConvertToCalendar(pData->TimeStamp), sizeof(RTC_CALENDAR_STRUCT));
        printf("    Time: %04u-%02u-%02u %02u:%02u:%02u.\r\n", stDBGCleandar.tm_year, stDBGCleandar.tm_mon, stDBGCleandar.tm_mday, stDBGCleandar.tm_hour, stDBGCleandar.tm_min, stDBGCleandar.tm_sec);
       
        // Check data.
        FLASH_ReadArray((uint8_t*)(&stDataItemDataCmp), uiDataAddress, sizeof(GLB_DATAITEM));
        printf("Check data read from address %u(0x%08X).\r\n", uiDataAddress, uiDataAddress);
        printf("    Index: %u, Value: %8.2f.\r\n", stDataItemDataCmp.Index, stDataItemDataCmp.Value);
        memcpy(&stDBGCleandar, RTC_ConvertToCalendar(stDataItemDataCmp.TimeStamp), sizeof(RTC_CALENDAR_STRUCT));
        printf("    Time: %04u-%02u-%02u %02u:%02u:%02u.\r\n", stDBGCleandar.tm_year, stDBGCleandar.tm_mon, stDBGCleandar.tm_mday, stDBGCleandar.tm_hour, stDBGCleandar.tm_min, stDBGCleandar.tm_sec);
#endif
        printf("Write data finished.\r\n");
}





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

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2016-11-2 17:18:11 | 显示全部楼层
先调通读写,然后慢慢调大数据读写
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

22

主题

133

帖子

2

精华

高级会员

Rank: 4

积分
901
金钱
901
注册时间
2015-12-24
在线时间
197 小时
 楼主| 发表于 2016-11-2 17:35:14 | 显示全部楼层
龙之谷 发表于 2016-11-2 17:18
先调通读写,然后慢慢调大数据读写

现在刚好反过来,32字节的结构体读写成功了,16字节的结构体读写失败。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-24 16:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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