Incrementing an int in a C code for microcontroller only moves the LSB

381 views Asked by At

I am wondering if someone could help me with a strange problem I'm having with the Silicon Labs C8051F040.

The problem is that I am using an unsigned int variable as a counter, which means that naturally I need to do something like variable++.

Well, my problem is that when the variable is allocated in the embedded memory the increment is OK

But when it is allocated in the external memory (not really external, but not embedded in the core), the LSB is incremented OK but the MSB is always in FF until an overflow happens, which sets it to 00 and after a new increment, it turns to FF again until a new overflow of the LSB.

I made a main() with only variable++ as instruction, and the same problem happens.

I tried to move the variable along the different parts of the external memory and the same happens. I read the ASM code generated by the compiler and the instructions look OK.

I really don't know what to do with this... I also "played" with the amounts of stack and heap memory without luck...

__xdata int variable;

void main()
{
  variable = 0;
  while (1)
  {
    variable++;
  }
}

What I can see with the debugger is that the variable starts with 0x0000 and after the first itaration the value reachs the 0xFF01, then 0xFF02, 0xFF03, etc. until 0xFFFF, when the next iterations set the value to 0x0000 and then start again with 0xFF01.

If instate of declaring the variable in the __xdata memory I use the __data memory, there is no problem. I can't copy the ASM code now 'cause I'm not in the lab, but I have to say that is correct, I'm sure about it.

I think that I'm having a memory problem related with the memory distribution, could be?

Thanks

1

There are 1 answers

0
Phil Wetzel On

I tried to duplicate your issue with Keil C51, and it should not be a surprise that I did not see your problem.

I suspect you are using the debugger incorrectly, perhaps looking at the wrong address or interpreting with the wrong type?

For you to compare, here is the ASM listing generated by the Keil compiler.

     6: void main() 
     7: { 
     8:   variable = 0; 
C:0x0800    E4       CLR      A
C:0x0801    900000   MOV      DPTR,#C_STARTUP(0x0000)
C:0x0804    F0       MOVX     @DPTR,A
C:0x0805    A3       INC      DPTR
C:0x0806    F0       MOVX     @DPTR,A
     9:   while (1) 
    10:   { 
    11:     variable++; 
C:0x0807    900001   MOV      DPTR,#0x0001
C:0x080A    E0       MOVX     A,@DPTR
C:0x080B    04       INC      A
C:0x080C    F0       MOVX     @DPTR,A
C:0x080D    70F8     JNZ      C:0807
C:0x080F    900000   MOV      DPTR,#C_STARTUP(0x0000)
C:0x0812    E0       MOVX     A,@DPTR
C:0x0813    04       INC      A
C:0x0814    F0       MOVX     @DPTR,A
    12:   }