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!