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!

Parents
  • Thanks for answer!
    order_devider of course in range 0~31.

    Ejack Zhang sayd:

    R4~R7 contains the unsigned long digit and R0 contains how many rotations.
    

    Problem this: Why unsigned char order_devider (located by D:0x2B addres in data memory) placed to R1 instead R0, and R0 loaded with data memory by addres D:0x01 (no variable references to this address!) ?

    If i try to place function code directly to main code all works perfectly, and R0 loaded with corect value(with value of variable located in data or xdata memory and declareted as global variable in main.h, example). But when i use my function I get that: order_devider located by 0x2B addres in data memory placed to R1 (why? variable declarated as unsigned char!).

Reply
  • Thanks for answer!
    order_devider of course in range 0~31.

    Ejack Zhang sayd:

    R4~R7 contains the unsigned long digit and R0 contains how many rotations.
    

    Problem this: Why unsigned char order_devider (located by D:0x2B addres in data memory) placed to R1 instead R0, and R0 loaded with data memory by addres D:0x01 (no variable references to this address!) ?

    If i try to place function code directly to main code all works perfectly, and R0 loaded with corect value(with value of variable located in data or xdata memory and declareted as global variable in main.h, example). But when i use my function I get that: order_devider located by 0x2B addres in data memory placed to R1 (why? variable declarated as unsigned char!).

Children