Code:
;Linearise a non linear input by look-up table and linear interpolation ;For non linear devices such as thermistors,ldr's etc ;May also be used to generate non linear functions such as sine,cos,exp,log etc ;w -> f(w) processor 16f84 include p16f84.inc temp1 equ 0x0C temp2 equ 0x0D X1 equ 0X0E x2 equ 0x0F test equ 0x10 org 0 ;Test code for MPLAB simulator clrf test loop movf test,w call linearise brk1 incfsz test goto loop brk2 return linearise movwf temp1 andlw 0x0F ;extract interpolation factor (lower nibble) movwf temp2 swapf temp1,w ;extract look-up table index (upper nibble) andlw 0x0F addlw 1 movwf temp1 call functbl ;get index+1 movwf x2 decf temp1,w call functbl ;get index movwf x1 subwf x2,w rrf x2 ;save carry skpc ;carry set=positive slope sublw 0 ;slope is negative clrf temp1 ;clear result bsf temp1,3 ;add 0.5 for rounding setc ;flag bit to loop four times mloop rrf temp2 ;multiply temp2 and w skpnc addwf temp1 rrf temp1 ;divide by two btfss temp2,4 ;test for flag bit goto mloop movf temp1,w btfsc x2,7 addwf x1,w ;slope was positive btfss x2,7 subwf x1,w ;slope was negative return ;result in w functbl addwf pcl ;cosine as an example (easy to verify result) retlw D'255' ;0 deg retlw D'254' retlw D'250' retlw D'244' retlw D'236' retlw D'225' retlw D'212' retlw D'197' retlw D'180' ;45 deg retlw D'162' retlw D'142' retlw D'120' retlw D'98' retlw D'74' retlw D'50' retlw D'25' retlw D'0' ;90 deg end
See also:
David A Cary Says:
"Non-linear Data Transformations": a similar linear interpolation algorithm using shift-and-add to replace multiply; in C. http://www.bytecraft.com/Non-linear_Data_Transformations.
David A Cary Says:
Methods of Integer Multiplication and Division on a processor like the PIC that doesn't have built-in multiply instruction.