This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

大神们Help,cc2430 flash Erase之后寄存器异常被更改!

某次程序编译后程序出现了异常,程序大约如下

void CommandExecute(UINT16 temp)

{

  UINT16 addr16;

  EA = 0;





  if(FlashFailed == 0xFF) //120912 如果之前未写入重试清除/写入损坏的次数,表示次数为0

    FlashFailed = 0;
  HalFlashErase(61);

  for (addr = 0x1E800; addr < 0x1F000; addr=addr+128) //120912 根据清除地址检查是否清空

  {

  }

 

  EA = 1;

}

 

void HalFlashErase(UINT8 pg)

{

  while (FCTL & 0x80);

  FADDRH = pg << 1;

  asm("NOP");

  FWT = 0x2A;

  FCTL = 0x01;

  asm("NOP");

  while (FCTL & 0x80);

  asm("NOP");

}

发现到在HalFlashErase()之后R7寄存器异常被更改了(addr16被分配到R6和R7,所以addr16就被更改了)

以下附上我debug模式下的图片

可以看到图1的时候尚未进入HalFlashErase(),此时R7寄存器的值还是0x00

图2则是进入HalFlashErase()之后跳出来,R7寄存器的值居然被改变了,而且刚刚好就是FADDRH的值!!(我测试过几次不同的值,R7寄存器异常时值都会变成FADDRH的值)

 

程序运行时EA都是关闭的,所以不是被中断干扰,而且在执行HalFlashErase()的时候也没有使用到R7寄存器

最下面会附上IAR编译出来的Assembly code

 

注:

FADDRH = pg << 1;

上面这行的下面若再加一个NOP(也就是两个NOP),或者是删除原本的NOP

程序不知为何就正常了,R7就没被更改了

 

这是不是编译器或是2430的flash controler有bug.....不知为何R7会被更改

 

图1.

 

 图2.

//  299             if(FlashFailed == 0xFF) //120912 如果之前未写入重试清除/写入损坏的次数,表示次数为0

        MOV       A,#0x1

        LCALL   ?XSTACK_DISP0_8

        MOVX    A,@DPTR

        XRL        A,#0xff

        JNZ ??OadCommandExecute_40

//  300               FlashFailed = 0;

        CLR        A

        MOVX    @DPTR,A

//  301

//  302             HalFlashErase(61);

??OadCommandExecute_40:

        ; Setup parameters for call to function HalFlashErase

        MOV       R1,#0x3d

        LCALL   HalFlashErase & 0xFFFF

//  303

//  304             for (addr = 0x1E800; addr < 0x1F000; addr=addr+128) //120912 根据清除地址检查是否清空

        MOV       DPTR,#__Constant_1e800

        MOV       R0,#?V0 + 0

        LCALL   ?L_MOV_X

 

 

 

 

 

 

 

/  146 /**************************************************************************************************

//  147  * @fn          HalFlashErase

//  148  *

//  149  * @brief       This function erases the specified page of the internal flash.

//  150  *

//  151  * input parameters

//  152  *

//  153  * @param       pg - A valid flash page number to erase.

//  154  *

//  155  * output parameters

//  156  *

//  157  * None.

//  158  *

//  159  * @return      None.

//  160  **************************************************************************************************

//  161  */

 

        RSEG NEAR_CODE:CODE:NOROOT(0)

//  162 ROOT void HalFlashErase(UINT8 pg)

HalFlashErase:

        CFI Block cfiBlock3 Using cfiCommon0

        CFI Function HalFlashErase

//  163 {

        ; Saved register size: 0

        ; Auto size: 0

//  164   while (FCTL & 0x80);//120912 判断Flash控制器是否忙碌,如果忙碌就先等待

??HalFlashErase_0:

        MOV       A,0xae

        MOV       C,0xE0 /* A   */.7

        JC    ??HalFlashErase_0

//  165   FADDRH = pg << 1;

        MOV       A,R1

        CLR        C

        RLC        A

        MOV       0xad,A

//  166   asm("NOP");

        NOP

//  167   FWT = 0x2A;

        MOV       0xab,#0x2a

//  168   FCTL = 0x01;

        MOV       0xae,#0x1

//  169   asm("NOP"); //160523(0024_1)

        NOP

//  170   while (FCTL & 0x80);//120912 判断Flash控制器是否完成清除Flash的动作,如果未完成就等待

??HalFlashErase_1:

        MOV       A,0xae

        MOV       C,0xE0 /* A   */.7

        JC    ??HalFlashErase_1

//  171   asm("NOP");

        NOP

//  172 }

        RET

        CFI EndBlock cfiBlock3