搜索

[应用方案] 关于M051 读写dataflash不稳定可靠

[复制链接]
38|2
 楼主 | 2021-4-6 11:24 | 显示全部楼层 |阅读模式

具体是这样的:

      在dataflash定义了54个字节,做用户数据区域,在第1,2个位置赋值AA 55作为是否初始化数据区域的标志位,上电读入第1,2位置的数据如果是AA 55就不初始化这数据区域,否则就要初始化用户的数据(这些数据后面程序要调用),经过反复测试,有偶尔出现读出来数据不是AA,55,导致数据被用户初始化,由于这区域在使用过程中,用户要存储一下资料,事实上在线进行读写也偶尔出现问题,帮忙分析一下!太诡异了

下面上一段函数的初始化程序:


#include "SmartM_M0.h"

/****************************************

*函数名称:ISPTriger

*输    入:无

*输    出:无

*功    能:ISP执行

******************************************/

void ISPTriger(void)

{

    ISPTRG |= ISPGO;

    while((ISPTRG&ISPGO) == ISPGO);

}

/****************************************

*函数名称:ISPEnable

*输    入:无

*输    出:无

*功    能:ISP使能

******************************************/

void ISPEnable(void)

{

    ISPCON |= ISPEN|CFGUEN|LDUEN;

}

/****************************************

*函数名称:ISPDisable

*输    入:无

*输    出:无

*功    能:ISP禁用

******************************************/

void ISPDisable(void)

{

    ISPCON &= ~(ISPEN|CFGUEN|LDUEN);

}

/****************************************

*函数名称:FMC_Erase

*输    入:unPage 页地址

*输    出:无

*功    能:数据区擦除

******************************************/

void FMC_Erase(UINT32 unAddr)

{

    /* 调用宏函数PROTECT_REG */

    PROTECT_REG(

        /* ISP使能 */

    ISPEnable();

        /* ISP命令:擦除 */

    ISPCMD = PAGE_ERASE;

    /* ISP操作的地址 */

    ISPADR = unAddr;

        /* ISP执行 */

    ISPTriger();

    /* ISP关闭 */

    ISPDisable();     


    )       


}

/****************************************

*函数名称:FMC_Write

*输    入:pucBuf 写数据缓冲区

                      unSize 写数据大小

*输    出:无

*功    能:数据区写

******************************************/

void FMC_Write(UINT32 unAddr,UINT8 *pucBuf,UINT32 unSize)

{

    UINT32 i;   

       

        /* 调用宏函数PROTECT_REG */

    PROTECT_REG(

       

        /* ISP使能 */

    ISPEnable();

       

        /* ISP命令:写 */

    ISPCMD = PROGRAM;


                for(i=0; i<unSize; i+=4)

                {

                        /* ISP操作的地址 */

                                ISPADR = (i+unAddr);

                                /* ISP写入字数据 */

                                ISPDAT = *(UINT32 *)(&pucBuf);

                                /* ISP执行 */

                                ISPTriger();

                               

                }

    /* ISP关闭 */

    ISPDisable();   


    )               


}


/****************************************

*函数名称:FMC_Read

*输    入:pucBuf 读数据缓冲区

                  unSize 读数据大小

*输    出:无

*功    能:数据区读

******************************************/

void FMC_Read(UINT32 unAddr,UINT8 *pucBuf,UINT32 unSize)

{

    UINT32 i;

       

        /* 调用宏函数PROTECT_REG */

    PROTECT_REG(

       

        /* ISP使能 */

    ISPEnable();

       

       

        /* ISP命令:读 */

    ISPCMD = READ;


    for(i=0; i<unSize; i+=4)

    {

            /* ISP操作的地址 */

            ISPADR = (i+unAddr);

                /* ISP执行 */

        ISPTriger();

               

                /* ISP读取字数据 */

                *(UINT32 *)(&pucBuf)=ISPDAT;

    }

       

    /* ISP关闭 */

    ISPDisable();   


    )

}


void InitialEeprom(void)

{

        uchar temp;

        uchar tempbuff[54];

       //有趣的是一定要定义局部数组,才可以成功,全局数组//变量基本是不成功读写

          DelaymS(50);//加延时没什么用

    FMC_Read(DATAFLASH_START_ADDRESS, tempbuff,54);DelaymS(50);

   if(tempbuff[0]==0xaa&&tempbuff[1]==0x55&&tempbuff[52]==0xcc&&tempbuff[53]==0xdd)goto exitint;

    FMC_Read(DATAFLASH_START_ADDRESS, tempbuff,54);DelaymS(50);

   if(tempbuff[0]==0xaa&&tempbuff[1]==0x55&&tempbuff[52]==0xcc&&tempbuff[53]==0xdd)goto exitint;

     FMC_Read(DATAFLASH_START_ADDRESS, Uart0_Recbuff0,54);DelaymS(50);

   if(tempbuff[0]==0xaa&&tempbuff[1]==0x55&&tempbuff[52]==0xcc&&tempbuff[53]==0xdd)goto exitint;

   else if( tempbuff[0]!=0xaa||tempbuff[1]!=0x55||

         tempbuff[52]!=0xcc||tempbuff[53]!=0xdd)

           {

   initloop:         

                   FMC_Erase(DATAFLASH_START_ADDRESS);

            memcpy(tempbuff,InitEEpromdata, sizeof(InitEEpromdata));

            FMC_WriteWithbuf(DATAFLASH_START_ADDRESS,tempbuff,54);

      FMC_Read(DATAFLASH_START_ADDRESS,tempbuff,54);


      if(tempbuff[0]==0xaa&&tempbuff[1]==0x55&&tempbuff[52]==0xcc&&tempbuff[53]==0xdd){goto exitint;}

      else goto initloop;

     }

exitint: ;


}



使用特权

评论回复
| 2021-4-6 16:39 | 显示全部楼层
可以試試連續讀取5~10次,只要一次成功即是成功,讀取5~10次皆不成功,才算失敗,再做Erase動作。

使用特权

评论回复
| 2021-4-6 16:39 | 显示全部楼层
可能是正在写FLASH时,偶尔会发生掉电的情况,还没写完就没电了,所以数据就不对了。

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表