; CC5X Version 3.4, Copyright (c) B Knudsen Data ; C compiler for the PICmicro family ; ************ 24. Jun 2009 9:07 ************* processor 16C54 radix DEC Carry EQU 0 Zero_ EQU 2 value EQU 0x08 scaledValue EQU 0x0A i EQU 0x07 ; FILE test\scaling.c ;/* ; 16 BIT LINEAR SCALING ROUTINE ; ============================= ; ; Copyright (c) B. Knudsen Data, 2000. This code can be used in any ; application at the responsibility of the application designer. ; Any publishing of this code requires dedicated permission. ; ; 16 bit linear scaling routine: y = K * x; ; ; NOTE: Requires that 'y' ranges from 0 .. 2^N-1 (N = 9..16), ; that is 0..0x1FF (or 0x3FF, 0x7FF, .. 0xFFFF). ; ; Example: A number ranging from 0..14999 is transformed to ; a number ranging from 0..0x1FFF (8191). Then: ; ; y = (8192/15000) * x = 0.546133 * x; ; ; The scaling routine performs the equivalent of floating point ; multiplication, fast and using few instructions (only 29). ; ; Timing: Maximum 8+N*26 (=424 for N=16) Instruction Cycles ; Typical 250-350 Instruction Cycles ; ; ScalingMax is the upper limit of 'x'. The result value ('y') can ; be smaller or greater than ScalingMax. If 'x' is equal to ; ScalingMax, then all result bits will be 1's. ;*/ ; ; ;#define ScalingMax 15000 // can optionally be a 16 bit variable ;#define ScalingBits 13 // number of bits in scaledValue (9..16) ; ;uns16 value; // input value, contains the remainder after scaling ;uns16 scaledValue; // new value ; ;/* Note that when 'y' is 8 bits or lower, then the type of ; 'scaledValue' can be changed to 'uns8' */ ; ; ;void scaling( void) ;{ scaling ; char i = ScalingBits; MOVLW 13 MOVWF i ; scaledValue = 0; CLRF scaledValue CLRF scaledValue+1 ; Carry = 0; BCF 0x03,Carry ; do { ; value = rl( value); // shift in 0 m001 RLF value,1 RLF value+1,1 ; ; #if ScalingMax >= 0x8000 ; if ( Carry) ; goto SUBTRACT; ; #endif ; ; if ( value >= ScalingMax) { MOVLW 58 SUBWF value+1,W BTFSS 0x03,Carry GOTO m003 BTFSS 0x03,Zero_ GOTO m002 MOVLW 152 SUBWF value,W BTFSS 0x03,Carry GOTO m003 ; SUBTRACT: ; value -= ScalingMax; m002 MOVLW 58 SUBWF value+1,1 MOVLW 152 SUBWF value,1 BTFSS 0x03,Carry DECF value+1,1 ; Carry = 1; BSF 0x03,Carry ; } ; // else Carry = 0; // ok ; scaledValue = rl( scaledValue); // shift in 0 or 1 m003 RLF scaledValue,1 RLF scaledValue+1,1 ; ; } while ( --i > 0); DECFSZ i,1 GOTO m001 ;} RETLW 0 ; ; ;// EXAMPLE : ; ;void main( void) ;{ main ; value = 1000; MOVLW 232 MOVWF value MOVLW 3 MOVWF value+1 ; scaling(); CALL scaling ; // scaledValue is then : 1000 * (8192 / 15000) = 546 ;} SLEEP ORG 0x01FF GOTO main END ; *** KEY INFO *** ; 0x0000 29 word(s) 5 % : scaling ; 0x001D 6 word(s) 1 % : main ; RAM usage: 5 bytes (1 local), 20 bytes free ; Maximum call level: 1 ; Total of 36 code words (7 %)