This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Maybe C51 bag? or C?ULSHR using trouble

In my project i try to creat function implements easy average filter

unsigned int    uint_average_filter (unsigned int  *buffer, unsigned char order, unsigned char order_devider);


First parameter it's pointer to buffer with sampled values,
Second parameter it's number of sample in buffer,
Third parameter it's "divider" for shift operation after sum of sampled value.
Function code:

unsigned int uint_average_filter (unsigned int  *buffer, unsigned char order, unsigned char order_devider){
unsigned char counter = 0;
unsigned long acc = 0;
for(counter = 0; counter<order; counter++){
   acc += buffer[counter];
}
acc >>=order_devider; // wrong result here!!!!!
return acc;
}


When i try to use my function i get wrong result, and i see Disassembly code for this function:

...
C:0x074B    AF30     MOV      R7,0x30
C:0x074D    AE2F     MOV      R6,0x2F
C:0x074F    AD2E     MOV      R5,0x2E
C:0x0751    AC2D     MOV      R4,0x2D
C:0x0753    A92B     MOV      R1,0x2B
C:0x0755    A801     MOV      R0,0x01
C:0x0757    120B02   LCALL    C?ULSHR(C:0B02)
C:0x075A    8F30     MOV      0x30,R7
C:0x075C    8E2F     MOV      0x2F,R6
C:0x075E    8D2E     MOV      0x2E,R5
C:0x0760    8C2D     MOV      0x2D,R4
C:0x0762    22       RET


From C:0x074B to C074D i see load acc value to R4 to R7 register, next two instruction must load order_devider(value placed to D:0x2B in data memory) to R0 (for function C?ULSHR) but D:0x2B placed ro R1 and to R0 loaded value located in data memory by address 0x01?? Where i wrong??

If parameter order_divider replace by constant value(example 0x04) i have correct code:

C:0x074B    AF30     MOV      R7,0x30
C:0x074D    AE2F     MOV      R6,0x2F
C:0x074F    AD2E     MOV      R5,0x2E
C:0x0751    AC2D     MOV      R4,0x2D
C:0x0755    A801     MOV      R0,#0x04
C:0x0757    120B02   LCALL    C?ULSHR(C:0B02)
C:0x075A    8F30     MOV      0x30,R7
C:0x075C    8E2F     MOV      0x2F,R6
C:0x075E    8D2E     MOV      0x2E,R5
C:0x0760    8C2D     MOV      0x2D,R4
C:0x0762    22       RET

and this works fine.

Thaks for help!