某次程序编译后程序出现了异常,程序大约如下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 func
tion 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
0