C 函数定义如下:
static void SetIAP(unsigned char newstate)
{
#if 1
unsigned char temp;
temp=CHPCON;
temp&=~(0x41);
if(newstate==ENABLE)
{
temp|=0x01;
}
TA=0xAA;
TA=0x55;
CHPCON=temp;
#endif
}
编译后的汇编代码如下:
708: static void SetIAP(unsigned char newstate)
709: {
710: #if 1
711: unsigned char temp;
712: temp=CHPCON;
C:0x151E AE9F MOV R6,CHPCON(0x9F)
713: temp&=~(0x41);
C:0x1520 EE MOV A,R6
C:0x1521 54BE ANL A,#0xBE
C:0x1523 FE MOV R6,A
714: if(newstate==ENABLE)
C:0x1524 EF MOV A,R7
C:0x1525 B40104 CJNE A,#u8Receive_Buffer_Size(0x01),C:152C
715: {
716: temp|=0x01;
C:0x1528 EE MOV A,R6
C:0x1529 4401 ORL A,#u8Receive_Buffer_Size(0x01)
C:0x152B FE MOV R6,A
717: }
718: TA=0xAA;
C:0x152C 75C7AA MOV TA(0xC7),#0xAA
719: TA=0x55;
C:0x152F 75C755 MOV TA(0xC7),#0x55
720: CHPCON=temp;
721: #endif
722:
723:
C:0x1532 AF06 MOV R7,0x06
C:0x1534 8F9F MOV CHPCON(0x9F),R7
724: }
C:0x1536 22 RET
问题来了,数据手册要求写完TA 0xAA,和0x55后的4个时钟周期内需要完成被保护寄存器的写工作,可是编译器编译成了两条指令,导致无法完成写入,在局部变量前加register 关键字,似乎也不起作用,当然此处C程序可以换种方式来些,但是对于被保护的寄存器有多种状态,条件判断写入时,似乎就不好处理了。这种结构的写法在其他有些函数中,局部变量被分配到寄存器,就不存在问题了,但是随着代码的增加,也不知道最终编译器是否使用了寄存器来定义局部变量。
C函数换成以下结构:
static void SetIAP(unsigned char newstate)
{
if(newstate==ENABLE)
{
TA=0xAA;
TA=0x55;
CHPCON|=0x01;
}
else
{
TA=0xAA;
TA=0x55;
CHPCON&=~0x01;
}
}
汇编结果就没有问题了,编译后的代码如下:
708: static void SetIAP(unsigned char newstate)
709: {
710: if(newstate==ENABLE)
C:0x0063 EF MOV A,R7
C:0x0064 B4010A CJNE A,#u8Receive_Buffer_Size(0x01),C:0071
711: {
712: TA=0xAA;
C:0x0067 75C7AA MOV TA(0xC7),#0xAA
713: TA=0x55;
C:0x006A 75C755 MOV TA(0xC7),#0x55
714: CHPCON|=0x01;
C:0x006D 439F01 ORL CHPCON(0x9F),#u8Receive_Buffer_Size(0x01)
715: }
716: else
C:0x0070 22 RET
717: {
718: TA=0xAA;
C:0x0071 75C7AA MOV TA(0xC7),#0xAA
719: TA=0x55;
C:0x0074 75C755 MOV TA(0xC7),#0x55
720: CHPCON&=~0x01;
C:0x0077 539FFE ANL CHPCON(0x9F),#EIP1(0xFE)
721: }
722: }
730:
C:0x007A 22 RET
以上的分析,对于以下函数就无法处理了:
void SetExtClock(unsigned char Source , unsigned char State)
{
unsigned char CKEN_Temp;
unsigned char EAFlag;
CKEN_Temp=CKEN;
switch(Source)
{
case CLK_EXT_DISABLE:
CKEN_Temp&=~0xC0;//clear bit7,6
break;
case CLK_EXT_FLXT:
CKEN_Temp&=~0xC0;//clear bit7,6
if(State)
{
CKEN_Temp|=0x40;
}
break;
case CLK_EXT_FHXT:
CKEN_Temp&=~0xC0;//clear bit7,6
if(State)
{
CKEN_Temp|=0x80;
}
break;
case CLK_EXT_FECLK:
CKEN_Temp&=~0xC0;//clear bit7,6
if(State)
{
CKEN_Temp|=0xC0;
}
break;
case CLK_INTERNAL_FHIRC:
CKEN_Temp&=~0x20;//clear bit5
if(State)
{
CKEN_Temp|=0x20;
}
break;
}
//set TA Protect
EAFlag=0;
if(EA)
{
EA=0;
EAFlag=1;
}
TA=0xAA;
TA=0x55;
CKEN=CKEN_Temp;
if(EAFlag)
{
EA=1;
}
}
求高手给予指导和解答!!!!
|