Hi,
I have a problem with a timer interrupt on a CC1110 (8051 with wireless interface) that I have been staring at for an hour with no success. 8051 is not a strength of mine so I would appreciate your comments -
Given the (very!) simple program:
char x; int main( void ) { char c = 0;
____IEN0 &= ~pdBIT_7; ____SetClockSource(); // Setup processor clock. ____vInitTimer3( 1000 );// Setup time to int every 1ms. ____P1DIR = 0xff; // P1 to output. ____IEN0 |= pdBIT_7;
____for( ;; ) ____{ ________x = c; // Do nowt but asign a char to a char. ____}
____return 0; }
__interrupt void T3_IRQ_C(void) { ____P1=~P1; // Toggle port 1 for viewing on a scope. ____TIMIF = 0; // Clear interrupt. }
the following assembler is generated for the for() loop.
000201 0E INC R6 x = c; 000202 EE MOV A,R6 000203 90 F2 00 MOV DPTR,#0xF200 000206 F0 MOVX @DPTR,A 000207 80 F8 SJMP 0x0201The scope shows that P1 is toggling with the expected frequency with a nice clean square wave. So far so good.
Now, if I change the code as follows: (Note that c is now volatile and incremented rather than assigned. The interrupt function is unchanged.)
int main( void ) { volatile char c = 0;
____IEN0 &= ~pdBIT_7; ____SetClockSource(); // Setup processor clock. ____vInitTimer3( 1000 );// Setup time to int every 1ms. ____P1DIR = 0xff; // P1 to output. ____IEN0 |= pdBIT_7;
____for( ;; ) ____{ ________c++; // Do nowt but asign a char to a char. ____}
____return 0; }
the following asm is generated:
00020C 85 10 82 MOV DPL,XSP(L) 00020F 85 11 83 MOV DPH,XSP(H) 000212 E0 MOVX A,@DPTR 000213 24 01 ADD A,#0x01 000215 F0 MOVX @DPTR,A 000216 80 F4 SJMP 0x020CWith the processor sat in this tight loop the scope shows that lots of timer interrupts are being missed, and there is no longer a clean square wave being output on P1.
If I disable and enable interrupts around the line where c is incremented I find that the clean square wave returns and timer interrupts are no longer missed, so I was postulating that an interrupt occurring between the sequential access of the two XSPbytes might have been causing some corruption within the ISR, but the code generated for the interrupt is as follows:
T3_IRQ_C: 0003CB C0 E0 PUSH A P1=~P1; 0003CD E5 90 MOV A,P1 0003CF F4 CPL A 0003D0 F5 90 MOV P1,A TIMIF = 0; 0003D2 75 D8 00 MOV TIMIF,#0x00
0003D5 D0 E0 POP A 0003D7 32 RETIso does not access the DPL, DPLH, XSP(L) or XSP(H) registers.
Either there is something seriously amiss or I have done something too dumb for me to see.