ON 20140408@10:12:28 PM at page: On a web page you were interested in at: http://techref.massmind.org/Techref/io/servo/wav.htm#41737.9253125 James Newton[JMN-EFP-786] See also: http://www.slideshare.net/wolfpaulus/android-arduino-and-the-headphone-jack FSK data encoding by Arduino read by Android via FFT ON 20140409@4:52:53 PM at page: On a web page you were interested in at: http://techref.massmind.org/Techref/member/petergharrison-btinternet-/index.htm#41738.7033912037 James Newton[JMN-EFP-786] Code:
;.......;.......;.......;.......;.......;.......;.......;.......;.......;.......;.......; ;**************************************************************************************** ; Filename: 18Fmathstest.asm * ; Date: 10/07/2013 * ; Author: Peter G Harrison * ; Company: PGH Consultants * ;**************************************************************************************** ; Files required: 18F4520_g.lkr Generic linker script for the PIC18F4520 * ; P18F4520.inc * ; 18Fmathstest.inc Configuration definition * ;**************************************************************************************** ;Revision History: * ;**************************************************************************************** ; ;**************************************************************************************** processor 18F4520 ; * list p=18F4520, n=65 ; define processor and pagelength * #include <P18F4520.inc> ; processor specific variable definitions * #include <18Fmathstest.inc> ; application specific config definitions * errorlevel -302,-306 ; suppress message 302 from list file * ;**************************************************************************************** ; ;**************************************************************************************** ;Define data variables * ;**************************************************************************************** ;**************************************************************************************** ;ACCESS ram - addressed directly * ;Groups separated to assist in register visibility during debug * ;**************************************************************************************** ; ;Maths - 4 byte accumulator registers group0 udata_acs 0x000 acc1_6 res 1 ; acc1_5 res 1 ; acc1_4 res 1 ; acc1_3 res 1 ; acc1_2 res 1 ; acc1_1 res 1 ; ; group1 udata_acs 0x008 acc2_6 res 1 ; acc2_5 res 1 ; acc2_4 res 1 ; main results register acc2_3 res 1 ; acc2_2 res 1 ; acc2_1 res 1 ; ; group2 udata_acs 0x010 acc3_6 res 1 ; acc3_5 res 1 ; acc3_4 res 1 ; acc3_3 res 1 ; acc3_2 res 1 ; acc3_1 res 1 ; ; group3 udata_acs 0x018 acc4_6 res 1 ; acc4_5 res 1 ; acc4_4 res 1 ; acc4_3 res 1 ; acc4_2 res 1 ; acc4_1 res 1 ; ; group4 udata_acs 0x020 mult_tmp res 1 ; maths temporary store shft_cnt res 1 ; multiplication and division loop count ; ;=======================================================================================* ;End of data area definition * ;=======================================================================================* ; ;**************************************************************************************** ;Baud rate constant calculations * ;**************************************************************************************** ; ;Serial I/O base frequency and system clock xtal_f equ d'7372800' ; OSC freq in Hz (gives exact baud rates) ; baud_9600 equ (xtal_f/(4*d'9600'))-1 baud_19200 equ (xtal_f/(4*d'19200'))-1 baud_38400 equ (xtal_f/(4*d'38400'))-1 baud_57600 equ (xtal_f/(4*d'57600'))-1 baud_115200 equ (xtal_f/(4*d'115200'))-1 ; ;Calculate baudrate when BRGH = 1 #define calc(baudrate) (xtal_f/(4*d'baudrate'))-1 ; ;**************************************************************************************** ; ;======================================================================================== ;Start of Programme * ;======================================================================================== ; RESET_VECTOR CODE 0x000 ; processor reset vector goto Start ; go to initialisation ; HPINT_VECTOR CODE 0x008 ; processor interrupt vector goto hprinth ; go to high priority interrupt handler routines ; LPINT_VECTOR CODE 0x018 ; processor interrupt vector goto lprinth ; go to low priority interrupt handler routines ; ; ;**************************************************************************************** ;**************************************************************************************** MAIN CODE 0x050 ; allow room for message strings ; ;======================================================================================== ;High priority interrupt routines * ;======================================================================================== ; hprinth retfie ; return from interrupt and re-enable ; ;======================================================================================== ;Low priority interrupt routines * ;======================================================================================== ; lprinth retfie ; return from interrupt and re-enable ; ; ;======================================================================================== ;Main * ;======================================================================================== ; ; clr1_4 ; acc1_4, acc1_3, acc1_2, acc1_1 = 0 ; clr1_2 ; acc1_2, acc1_1 = 0 ; clr2_4 ; acc2_4, acc2_3, acc2_2, acc2_1 = 0 ; clr2_2 ; acc2_2, acc2_1 = 0 ; clr3_4 ; acc1_4, acc1_3, acc1_2, acc1_1 = 0 ; clr3_2 ; acc1_2, acc1_1 = 0 ; clr4_4 ; acc2_4, acc2_3, acc2_2, acc2_1 = 0 ; clr4_2 ; acc2_2, acc2_1 = 0 ; ; sub16 ; 16 bit subtract, acc2 - acc1 -> acc2 ; add16 ; 16 bit add, acc2 + acc1 -> acc2 ; ; inc2 ; 32 bit increment acc2 + 1 -> acc2 ; dec2 ; 32 bit decrement acc2 - 1 -> acc2 ; ; sub32 ; 32 bit subtract, acc2 - acc1 -> acc2 ; add32 ; 32 bit add, acc2 + acc1 -> acc2 ; ; comp1 ; 32 bit 2's complement -acc1 -> acc1 ; comp2 ; 32 bit 2's complement -acc2 -> acc2 ; ; mul16 ; 16*16 multiply, acc2 x acc1 -> acc2 ; div2by1 ; 32/16 divide, acc2/acc1 -> acc2 (R hi, Q lo) ; div32 ; 32/16 divide, acc2/acc1 -> acc2 (R hi, Q lo) ; div48 ; 48/24 divide, acc2/acc1 -> acc2 (R hi, Q lo) ; ; sqrt16 ; 16 bit square root acc2_2:acc2_1 -> acc2_1 ; sqrt32 ; 32 bit square root acc2_4:acc2_1 -> acc1_2:1 ; ;======================================================================================== ; begin ;======================================================================================== ;Maths Routines * ;======================================================================================== ;Development basic maths routines call sub32 ; 32 bit subtract, acc2 - acc1 -> acc2 call add32 ; 32 bit add, acc2 + acc1 -> acc2 call comp1 ; 32 bit 2's complement -acc1 -> acc1 call comp2 ; 32 bit 2's complement -acc2 -> acc2 call mul16 ; 16*16 multiply, acc2 x acc1 -> acc2 call div2by1 ; 32/16 divide, acc2/acc1 -> acc2 (R hi, Q lo) call sqrt16 ; 16 bit square root acc2_2/1 -> acc2_1 call sqrt32 ; 32 bit square root acc2_4:acc2_1 -> acc1_2/1 call sqrt48 ; 48 bit square root acc2_6:acc2_1 -> acc1_3/2/1 ; ;Test routines call sqrt16test ; test routine for 16 bit square root extraction call sqrt32test ; test routine for 32 bit square root extraction call sqrt48test ; test routine for 48 bit square root extraction goto begin ; ; ;======================================================================================== ;Clear accumulators acc1 to to acc4 ;======================================================================================== ; clr1_6 clrf acc1_6 ; clear acc1 clrf acc1_5 ; clr1_4 clrf acc1_4 ; clrf acc1_3 ; clr1_2 clrf acc1_2 ; clrf acc1_1 ; return ; clr2_6 clrf acc2_6 ; clear acc2 clrf acc2_5 ; clr2_4 clrf acc2_4 ; clrf acc2_3 ; clr2_2 clrf acc2_2 ; clrf acc2_1 ; return ; clr3_6 clrf acc3_6 ; clear acc3 clrf acc3_5 ; clr3_4 clrf acc3_4 ; clrf acc3_3 ; clr3_2 clrf acc3_2 ; clrf acc3_1 ; return ; clr4_6 clrf acc4_6 ; clear acc4 clrf acc4_5 ; clr4_4 clrf acc4_4 ; clrf acc4_3 ; clr4_2 clrf acc4_2 ; clrf acc4_1 ; return ; ;======================================================================================== ;Unsigned 16 bit subtract. acc2_2:acc2_1 - acc1_2:acc1_1 -> acc2_2:acc2_1 * ;======================================================================================== ; sub16 movf acc1_1,w ; unsigned 16 bit subtract subwf acc2_1 ; movf acc1_2,w ; subwfb acc2_2 ; return ; ;======================================================================================== ;Unsigned 32 bit subtract. acc2_4:acc2_1 - acc1_4:acc1_1 -> acc2_4:acc2_1 * ;======================================================================================== ; sub32 movf acc1_1,w ; unsigned 32 bit subtract subwf acc2_1 ; movf acc1_2,w ; subwfb acc2_2 ; movf acc1_3,w ; subwfb acc2_3 ; movf acc1_4,w ; subwfb acc2_4 ; return ; ;======================================================================================== ;Unsigned 48 bit subtract. acc2_6:acc2_1 - acc1_6:acc1_1 -> acc2_6:acc2_1 * ;======================================================================================== ; sub48 movf acc1_1,w ; unsigned 32 bit subtract subwf acc2_1 ; movf acc1_2,w ; subwfb acc2_2 ; movf acc1_3,w ; subwfb acc2_3 ; movf acc1_4,w ; subwfb acc2_4 ; movf acc1_5,w ; subwfb acc2_5 ; movf acc1_6,w ; subwfb acc2_6 ; return ; ;======================================================================================== ;Unsigned 16 bit add. acc2_2:acc2_1 + acc1_2:acc1_1 -> acc2_2:acc2_1 * ;======================================================================================== ; add16 movf acc1_1,w ; unsigned 16 bit add addwf acc2_1 ; movf acc1_2,w ; addwfc acc2_2 ; return ; ;======================================================================================== ;Unsigned 32 bit add. acc2_4:acc2_1 + acc1_4:acc1_1 -> acc2_4:acc2_1 * ;======================================================================================== ; add32 movf acc1_1,w ; unsigned 32 bit add addwf acc2_1 ; movf acc1_2,w ; addwfc acc2_2 ; movf acc1_3,w ; addwfc acc2_3 ; movf acc1_4,w ; addwfc acc2_4 ; return ; ;======================================================================================== ;Unsigned 48 bit add. acc2_6:acc2_1 + acc1_6:acc1_1 -> acc2_6:acc2_1 * ;======================================================================================== ; add48 movf acc1_1,w ; unsigned 32 bit add addwf acc2_1 ; movf acc1_2,w ; addwfc acc2_2 ; movf acc1_3,w ; addwfc acc2_3 ; movf acc1_4,w ; addwfc acc2_4 ; movf acc1_5,w ; addwfc acc2_5 ; movf acc1_6,w ; addwfc acc2_6 ; return ; ;======================================================================================== ;2's complement acc1_4:acc1_1 * ;======================================================================================== ; comp1 comf acc1_1 ; complement acc1 comf acc1_2 ; comf acc1_3 ; comf acc1_4 ; incfsz acc1_1,f ; return ; incfsz acc1_2,f ; return ; incfsz acc1_3,f ; return ; incfsz acc1_4,f ; return ; ;======================================================================================== ;2's complement acc1_4:acc1_1 * ;======================================================================================== ; comp2 comf acc2_1 ; complement acc2 comf acc2_2 ; comf acc2_3 ; comf acc2_4 ; incfsz acc2_1,f ; return ; incfsz acc2_2,f ; return ; incfsz acc2_3,f ; return ; incfsz acc2_4,f ; return ; ;======================================================================================== ;Unsigned 32/16 bit division (approx 552 to 712 cycles) ;Inputs: Dividend - acc2_4 -> acc2_1 (32 bits) ; Divisor - acc1_2 -> acc1_1 (16 bits) ;Temporary: Counter - count ;Output: Quotient - acc2_2 -> acc2_1 (32 bits) ; Remainder- acc1_4 -> acc1_3 (16 bits) ;======================================================================================== ; div32 movlw d'32' ; 32-bit divide by 16-bit movwf shft_cnt clrf acc1_4 ; clear remainder clrf acc1_3 ; dvloop bcf STATUS,C ; set quotient bit to 0, shift left dividend & quotient rlcf acc2_1 ; low byte rlcf acc2_2 rlcf acc2_3 rlcf acc2_4 ; msb into carry rlcf acc1_3 ; and then into partial remainder rlcf acc1_4 ; bc subdiv ; if overflow then remainder > divisor so can subtract movf acc1_2,w ; compare partial remainder and divisor subwf acc1_4,w bnz testgt ; if hi bytes =, check low bytes, else check for > ; movf acc1_1,w ; high bytes are = so compare low bytes subwf acc1_3,w testgt bnc remrlt ; if carry set remainder > divisor, so ok to subtract ; subdiv movf acc1_1,w ; subtract divisor from partial remainder subwf acc1_3,f movf acc1_2,w subwfb acc1_4,f bsf acc2_1,0 ; set quotient bit to 1 ; ; quotient replaces dividend which is lost remrlt decfsz shft_cnt goto dvloop return ; ;======================================================================================== ;Unsigned 32 / 16 bits division *** NOT SURE ABOUT THIS ROUTINE !!!! ****** ;Dividend in acc2_ (max val H'FFFE0001' =4,294,836,225) ;Divisor in acc1_ (max value H'FFFF' =65,535) ;Ensure being within range or if a division by zero is going to happen. ; ;Return: quotient in acc2_2:1 (16 bits) and remainder in acc2_4:3 (16 bits) ;Result of acc2_4:acc2_1 / acc1_2:acc1_1 => acc2_2:acc2_1 (quotient) ;affected register: shft_cnt ;Typically 262 cycles ;======================================================================================== ; div2by1 movlw d'16' ;initialize the movwf shft_cnt ;shift counter ; divloop bcf STATUS,C ;we ensure that b0 rlcf acc2_1,f ;of acc2_1 is =0 rlcf acc2_2,f ;after the shifting rlcf acc2_3,f ;to the left of the rlcf acc2_4,f ;whole dividend ; ;Test carry flag, if = 1, then shift caused overflow so subtract acc1_1 from acc2_3 bc subtrct movf acc1_2,w ; compare acc1_2 subwf acc2_4,w ; against acc2_4 ; ;Test zero flag, if = 0,then acc1_2 != acc2_4. so check if acc1_2 < acc2_4 bnz acc1les movf acc1_1,w ; acc1_2 = acc2_4; now compare subwf acc2_3,w ; value of acc1_1 against acc2_3 ; ;Test carry flag, if = 1, then DSOR_ < DEND_ , so subtract acc1_2:L from acc2_4:2 acc1les bnc dec_ctr ; ;subtract divisor from MSBs of dividend subtrct movf acc1_1,w ; acc2_3 = acc2_3 - acc1_1 subwf acc2_3,f ; borrow not used (LSB) movf acc1_2,w ; acc2_4 = acc2_4 - acc1_2 subwfb acc2_4,f ; borrow used bsf acc2_1,0 ; flag "divisor was substracted from dividend" ; dec_ctr decfsz shft_cnt,f bra divloop return ; finished ; ;======================================================================================== ;Unsigned 48/24 bit division (approx 967 to 1447 cycles) ;Inputs: Dividend - acc2_6 -> acc2_1 (48 bits) ; Divisor - acc1_3 -> acc1_1 (24 bits) ;Temporary: Counter - shft_cnt ;Output: Quotient - acc2_6 -> acc2_1 (48 bits) ; Remainder- acc1_6 -> acc1_4 (24 bits) ;======================================================================================== ; div48 movlw d'48' ; 48-bit divide by 24-bit movwf shft_cnt clrf acc1_6 ; Clear remainder clrf acc1_5 clrf acc1_4 ; divdlp bcf STATUS,C ; Set quotient bit to 0, shift left dividend & quotient rlcf acc2_1 ; low byte rlcf acc2_2 rlcf acc2_3 rlcf acc2_4 rlcf acc2_5 rlcf acc2_6 ; most significant bit into carry rlcf acc1_4 ; and then into partial remainder rlcf acc1_5 rlcf acc1_6 ; bc subtdiv ; If overflow then remainder must be > divisor ; ;After subtraction, if Z set then check less significant bytes. If Z not set and C ;is set, partial remainder > divisor, so can subtract and set result bit in acc2 ; movf acc1_3,w ; Compare high bytes of partial remainder and divisor subwf acc1_6,w bnz test_gt ; bytes not equal, so check if remainder > divisor ; movf acc1_2,w ; middle bytes of partial remainder and divisor subwf acc1_5,w bnz test_gt ; bytes not equal, so check if remainder > divisor ; movf acc1_1,w ; subwf acc1_4,w ; test_gt bnc rmdrlt ; carry set if partial remainder > divisor ; subtdiv movf acc1_1,w ; Subtract divisor from partial remainder subwf acc1_4,f movf acc1_2,w subwfb acc1_5,f movf acc1_3,w subwfb acc1_6,f bsf acc2_1,0 ; Set quotient bit to 1 ; ; Quotient replaces dividend which is lost rmdrlt decfsz shft_cnt goto divdlp return ; ;======================================================================================== ;Unsigned 16 * 16 bit multiplication ;acc1_2:acc1_1 * acc2_2:acc2_1 -> acc2_4:acc2_1 ;acc1 value remains unchanged. ;affected register: mult_tmp ;28cycles ;======================================================================================== ; mul16 movf acc2_2,w mulwf acc1_2 ; acc1_2 * acc2_2 movff PRODH,acc2_4 ; into result movff PRODL,acc2_3 ; movf acc2_1,w mulwf acc1_1 ; acc1_1 * acc2_1; movff PRODH,mult_tmp movff PRODL,acc2_1 ; mulwf acc1_2 ; acc1_2 * acc2_1 movf PRODL,w addwf mult_tmp,f ; Add cross movf PRODH,w ; products addwfc acc2_3,f clrf WREG addwfc acc2_4,f ; movf acc2_2,w mulwf acc1_1 ; acc1_1 * acc2_2 movf PRODL,w ; addwf mult_tmp,w ; Add cross movwf acc2_2 movf PRODH,w ; products addwfc acc2_3,f clrf WREG addwfc acc2_4,f return ; ;======================================================================================== ; Unsigned 24 * 24 bit multiplication ; acc1_3:acc1_1 * acc2_3:acc2_1 -> acc2_6:acc2_1 ; 148 cycles, including initial moves and register clearances ;======================================================================================== mul24 movff acc2_3,acc3_6 movff acc2_2,acc3_5 movff acc2_1,acc3_4 movff acc1_3,acc3_3 movff acc1_2,acc3_2 movff acc1_1,acc3_1 ; call clr2_6 call clr1_6 ; movf acc3_6,w mulwf acc3_1 movff PRODH,acc2_4 movff PRODL,acc2_3 ; movf acc3_3,w mulwf acc3_4 movff PRODH,acc1_4 movff PRODL,acc1_3 ; call add48 ; movf acc3_2,w mulwf acc3_6 movff PRODH,acc1_5 movff PRODL,acc1_4 ; mulwf acc3_4 movff PRODH,acc1_3 movff PRODL,acc1_2 ; call add48 ; movf acc3_5,w mulwf acc3_3 movff PRODH,acc1_5 movff PRODL,acc1_4 ; mulwf acc3_1 movff PRODH,acc1_3 movff PRODL,acc1_2 ; call add48 ; movf acc3_6,w mulwf acc3_3 movff PRODH,acc1_6 movff PRODL,acc1_5 ; movf acc3_5,w mulwf acc3_2 movff PRODH,acc1_4 movff PRODL,acc1_3 ; movf acc3_4,w mulwf acc3_1 movff PRODH,acc1_2 movff PRODL,acc1_1 ; call add48 ; return ; ;======================================================================================== ;16 bit square root - sqrt16 ;Return with carry set if negative ; ;Inputs: acc2_2 : acc2_1 ;Output: acc2_1 returns with the 8 bit result ; ;30 Instructions 104 Cycles best case, 109 average, 122 worst case ;======================================================================================== ; sqrt16 movlw 0xc0 ;Initialize value for mask movwf acc2_4 ;Mask movlw 0x40 ;Initial value for the root clrf STATUS ; sq1 subwf acc2_2,f ;Subtract the root developed so far btfss STATUS,C ;If it is larger than acc2_2 goto sq5 ;then go restore the subtraction ; sq2 iorwf acc2_4,w ;Set the current bit sq3 bcf STATUS,C ;!!!TEMP DEBUG - see move with no extra bits!!! rlcf acc2_1,f ;Shift N left one position rlcf acc2_2,f rrcf acc2_4,f ;Shift the mask right, and pick up msb of N btfsc acc2_4,7 ;If msb of N is set, then unconditionally goto sq6 ;set the next bit (because subtracting the ; ;root is guranteed not to cause a borrow) ; xorwf acc2_4,w ;Append "01" to the root developed so far btfss STATUS,C ;If the lsb of mask was shifted into the carry goto sq1 ;then we're done. Otherwise, loop again. ; ;We are almost done. In the last iteration, we have 7 bits of the root. When ;"01" is appended to it, we will have a 9-bit number that must be subtracted ;from N. ; subwf acc2_2,f ; btfss STATUS,C ;If the upper 7 bits cause a borrow, then goto exitsq ;the appended "01" will as well: We're done. ; btfsc STATUS,Z ;If the result of the subtraction is zero btfsc acc2_1,7 ;AND the msb of acc2_1 is set then the LSB of the ; ;root is zero. xorlw 1 ;Otherwise, it is one. exitsq movwf acc2_1 ;result to acc2_1 clrf acc2_2 ; return ; ; sq6 btfsc STATUS,C ;Need to unconditionally set current bit of root. goto exitsq ;However, if through iterating, then leave. Note, ;C is set by shifting mask right & the LSB of root ;was set by iorwf at sq2. ; bcf acc2_4,7 ;Clear the MSB of N that got shifted into the mask. xorwf acc2_4,w ;Append "01" to the root developed so far. subwf acc2_2,f ;Subtract goto sq2 ;Go unconditionally set the current bit. ; sq5 addwf acc2_2,f ;Restore acc2_2 by reversing the subwf with a ADDWF goto sq3 ;Don't set the current bit ; ;======================================================================================== ; SQRT32 ;; Calculates the square root of a 32 bit number using the binary restoring method. ; ; Input: acc2_4:acc2_1 ; Mask: acc3_2:acc3_1 ; Result: acc1_2:acc1_1 ; ; Takes between 395 and 457 cycles (incl. call and return). ; Uses 64 words ROM, 8 bytes RAM including 4 holding the input. ;======================================================================================== ; sqrt32 movlw 0x40 ; Initial value for Result is... movwf acc1_2 ; ... 01000000 00000000 clrf acc1_1 ; ; movlw 0xC0 ; Initial value for mask is... movwf acc3_2 ; ... 11000000 00000000 clrf acc3_1 ; (second '1' is loop counter). ; compare movf acc1_1,w ; Compare root-so-far with current subwf acc2_3,f ; ... remainder. movf acc1_2,w ; subwfb acc2_4,f ; bc $+4 ; goto restore ; result is -ve, so need to restore ; setcurr movf acc3_1,w ; set the current bit in the result. iorwf acc1_1,f ; movf acc3_2,w ; iorwf acc1_2,f ; ; shftUp rlcf acc2_1,f ; rlcf acc2_2,f ; rlcf acc2_3,f ; rlcf acc2_4,f ; ; rrcf acc3_2,f ; Shift mask right for next bit, whilst rrcf acc3_1,f ; ... shifting in MSB from remainder. btfsc acc3_2,7 ; If MSB is set, unconditionally set the goto setnext ; ... next bit. ; movf acc3_1,w ; Append '01' to root-so-far xorwf acc1_1,f ; movf acc3_2,w ; xorwf acc1_2,f ; ; bc $+4 ; If second '1' in mask is shifted out, goto compare ; ... then that was the last normal iteration. ; movf acc1_1,w ; Last bit Generation. subwf acc2_3,f ; ... The final subtract is 17-bit (15-bit root movf acc1_2,w ; ... plus '01'). Subtract 16-bits: if result subwfb acc2_4,f ; ... generates a carry, last bit is 0. bc $+4 ; return ; movf acc2_3,w ; Clear zero flag if remainder non zero xorwf acc2_4,w ; ; movlw 1 ; bnz $+4 ; If result is 0 AND msb of N is '0', result bit btfsc acc2_2,7 ; ... is 0, otherwise '1'. xorwf acc1_1,f ; return ; ; setnext bnc $+4 ; If mask has shifted out, leave. final bit return ; ... has been set by iorwf at in1. bcf acc3_2,7 ; clear bit shifted in from input. ; movf acc3_1,w ; Append '01' to root-so-far xorwf acc1_1,f ; movf acc3_2,w ; xorwf acc1_2,f ; ; movf acc1_1,w ; This subtraction is guaranteed not to subwf acc2_3,f ; ... cause a borrow, so subtract and movf acc1_2,w ; ... jump back to insert a '1' in the subwfb acc2_4,f ; ... root. goto setcurr ; ; restore movf acc1_1,w ; A subtract above at Sub_Cmp was -ve, so addwf acc2_3,f ; ... restore the remainder by adding. movf acc1_2,w ; The current bit of the root is zero. addwfc acc2_4,f ; goto shftUp ; ; ;======================================================================================== ; SQRT48 ; Calculates the square root of a 48 bit number using the binary restoring method. ; Input: acc2_6:acc2_1 ; Mask: acc3_3:acc3_1 ; Result: acc1_3:acc1_1 ; ; Takes between 810 and 890 cycles (incl. call and return). ; Uses 84 words ROM, 10 bytes RAM including 4 holding the input. ;======================================================================================== ; sqrt48 movlw 0x40 ; Initial value for Result is... movwf acc1_3 ; ... 01000000 00000000 00000000 clrf acc1_2 ; clrf acc1_1 ; ; movlw 0xC0 ; Initial value for mask is... movwf acc3_3 ; ... 11000000 00000000 00000000 clrf acc3_2 ; (second '1' is loop counter). clrf acc3_1 ; ; comp movf acc1_1,w ; Compare root-so-far with current subwf acc2_4,f ; ... remainder. movf acc1_2,w ; subwfb acc2_5,f ; movf acc1_3,w ; subwfb acc2_6,f ; bc $+4 ; goto undosub ; result is -ve, so need to restore ; setbit movf acc3_1,w ; set the current bit in the result. iorwf acc1_1,f ; movf acc3_2,w ; iorwf acc1_2,f ; movf acc3_3,w ; iorwf acc1_3,f ; ; upshft rlcf acc2_1,f ; rlcf acc2_2,f ; rlcf acc2_3,f ; rlcf acc2_4,f ; rlcf acc2_5,f ; rlcf acc2_6,f ; ; rrcf acc3_3,f ; Shift mask right for next bit, whilst rrcf acc3_2,f ; ... shifting in MSB from remainder. rrcf acc3_1,f ; btfsc acc3_3,7 ; If MSB is set, unconditionally set the goto nextset ; ... next bit. ; movf acc3_1,w ; Append '01' to root-so-far xorwf acc1_1,f ; movf acc3_2,w ; xorwf acc1_2,f ; movf acc3_3,w ; xorwf acc1_3,f ; ; bc $+4 ; If second '1' in mask is shifted out, goto comp ; ... then that was the last normal iteration. ; movf acc1_1,w ; Last bit Generation. subwf acc2_4,f ; ... The final subtract is 15-bit (23-bit root movf acc1_2,w ; ... plus '01'). Subtract 24-bits: if result subwfb acc2_5,f ; ... generates a carry, last bit is 0. movf acc1_3,w ; subwfb acc2_6,f ; bc $+4 ; return ; movf acc2_4,w ; Clear zero flag if remainder non zero xorwf acc2_5,w ; xorwf acc2_6,w ; ; movlw 1 ; bnz $+4 ; If result is 0 AND msb of N is '0', result bit btfsc acc2_3,7 ; ... is 0, otherwise '1'. xorwf acc1_1,f ; return ; ; nextset bnc $+4 ; If mask has shifted out, leave. final bit return ; ... has been set by iorwf at in1. bcf acc3_3,7 ; clear bit shifted in from input. ; movf acc3_1,w ; Append '01' to root-so-far xorwf acc1_1,f ; movf acc3_2,w ; xorwf acc1_2,f ; movf acc3_3,w ; xorwf acc1_3,f ; ; movf acc1_1,w ; This subtraction is guaranteed not to subwf acc2_4,f ; ... cause a borrow, so subtract and movf acc1_2,w ; ... jump back to insert a '1' in the subwfb acc2_5,f ; ... root. movf acc1_3,w ; subwfb acc2_6,f ; goto setbit ; ; undosub movf acc1_1,w ; A subtract above at Sub_Cmp was -ve, so addwf acc2_4,f ; ... restore the remainder by adding. movf acc1_2,w ; The current bit of the root is zero. addwfc acc2_5,f ; movf acc1_3,w ; addwfc acc2_6,f ; goto upshft ; ; ;======================================================================================== ;End of Main Task * ;======================================================================================== ; ;======================================================================================== ;16 bit square root routine test ;======================================================================================== sqrt16test clrf acc4_4 clrf acc4_3 clrf acc4_2 clrf acc4_1 ; loop16 incf acc4_1 bnz cont16 incf acc4_2 ; cont16 movff acc4_1,acc2_1 movff acc4_2,acc2_2 call sqrt16 goto loop16 ; ;======================================================================================== ;32 bit square root routine test ;======================================================================================== ; sqrt32test clrf acc4_4 clrf acc4_3 clrf acc4_2 clrf acc4_1 ; loop32 incf acc4_1 bnz cont32 incf acc4_2 bnz cont32 incf acc4_3 bnz cont32 incf acc4_4 ; cont32 movff acc4_1,acc2_1 movff acc4_2,acc2_2 movff acc4_3,acc2_3 movff acc4_4,acc2_4 call sqrt32 goto loop32 ; ;======================================================================================== ;48 bit square root routine test ;======================================================================================== ; sqrt48test clrf acc4_6 clrf acc4_4 clrf acc4_4 clrf acc4_3 clrf acc4_2 clrf acc4_1 ; loop48 incf acc4_1 bnz cont48 incf acc4_2 bnz cont48 incf acc4_3 bnz cont48 incf acc4_4 bnz cont48 incf acc4_5 bnz cont48 incf acc4_6 ; cont48 movff acc4_1,acc2_1 movff acc4_2,acc2_2 movff acc4_3,acc2_3 movff acc4_4,acc2_4 movff acc4_5,acc2_5 movff acc4_6,acc2_6 call sqrt48 goto loop48 ; ;======================================================================================== ;Processor initialisation * ;======================================================================================== ; Start ; Start of programme execution ; ;Set up oscllator control register movlw b'00000000' ; ; | |--------------; SCS0 ; | |---------------; SCS1 ; | |----------------; IOFS ; | |-----------------; OSTS ; | |------------------; IRCF0 ; | |-------------------; IRCF1 ; ||--------------------; IRCF2 ; |---------------------; IDLEN movwf OSCCON ; see page 32 of Data Sheet DS39631E ; ;Initialiise I/O ports ;setup PORTA movlw b'00001111' ; bits 0 - 3 as input, the rest as output movwf TRISA ; see page 105 of Data Sheet DS39631E ; setup PORTB movlw b'11111111' ; all inputs movwf TRISB ; see page 108 of Data Sheet DS39631E ;setup PORTC movlw b'11000010' ; ; | |--------------; T1OSO ; | |---------------; T1OSI ; | |----------------; RC2 ; | |-----------------; RC3 ; | |------------------; RC4 ; | |-------------------; RC5 ; ||--------------------; TX ; |---------------------; RX movwf TRISC ; see page 111 of Data Sheet DS39631E ; setup PORTD movlw b'00000000' ; set all as outputs movwf TRISD ; see page 114 of Data Sheet DS39631E ; setup PORTE movlw b'00000000' ; set all as outputs movwf TRISE ; see page 118 of Data Sheet DS39631E ; ;ADC configuration movlw b'00000000' ; ; | |--------------; ADON ; | |---------------; GO/DONE- ; | |----------------; CHS0 ; | |-----------------; CHS1 ; | |------------------; CHS2 ; | |-------------------; CHS3 ; ||--------------------; - ; |---------------------; - movwf ADCON0 ; see page 223 of Data Sheet DS39631E ; movlw b'00001011' ; ; | |--------------; PCFQ0 ; | |---------------; PCFQ1 ; | |----------------; PCFQ2 ; | |-----------------; PCFQ3 ; | |------------------; VCFG0 ; | |-------------------; VCFG1 ; ||--------------------; - ; |---------------------; - movwf ADCON1 ; see page 224 of Data Sheet DS39631E ; movlw b'10010101' ; right just, 4tad, Fosc/16 ; | |--------------; ADCS0 ; | |---------------; ADCS1 ; | |----------------; ADCS2 ; | |-----------------; ACQT0 ; | |------------------; ACQT1 ; | |-------------------; ACQT2 ; ||--------------------; - ; |---------------------; ADFM movwf ADCON2 ; see page 225 of Data Sheet DS39631E ; ;Comparator module configuration movlw b'11110101' ; common CVREF, AN0/AN1 inputs, invert both o/p ; | |--------------; CM0 ; | |---------------; CM1 ; | |----------------; CM2 ; | |-----------------; CIS ; | |------------------; C1INV ; | |-------------------; C2INV ; ||--------------------; C1OUT ; |---------------------; C2OUT movwf CMCON ; See page 233 of Data Sheet DS39631E ; movlw b'11001000' ; Ref on, high range, set to 50% (current 65uA) ; | |--------------; CRV0 ; | |---------------; CRV1 ; | |----------------; CRV2 ; | |-----------------; CRV3 ; | |------------------; CVRSS (0 = high range 1 = low range) ; | |-------------------; CVRR (0 = Vdd - Vss 1 = Vref+ - Vref-) ; ||--------------------; CVROE (0 = reference disconnected from AN2 pin) ; |---------------------; CVREN (1 = reference enabled) movwf CVRCON ; See page 239 of Data Sheet DS39631E ; ;Serial I/O configuration movlw h'00' ; 0 for 9600 baud movwf SPBRGH ; set high byte ; movlw calc(9600) ; calculate baudrate for 9600 with brgh=1 movwf SPBRG ; and store it ; movlw b'00001000' ; ; | |--------------; ADBEN ; | |---------------; WUE ; | |----------------; - ; | |-----------------; BRG16 ; | |------------------; TXCKP ; | |-------------------; RXDTP ; ||--------------------; RCIDL ; |---------------------; ABDOVF movwf BAUDCON ; see page 204 of Data Sheet DS39631E ; movlw b'00100100' ; ; | |--------------; TX9D ; | |---------------; TRMT ; | |----------------; BRGH ; | |-----------------; SENDB ; | |------------------; SYNC ; | |-------------------; TXEN ; ||--------------------; TX9 ; |---------------------; CSRC movwf TXSTA ; see page 202 of Data Sheet DS39631E ; movlw b'10010000' ; ; | |--------------; RX9D ; | |---------------; OERR ; | |----------------; FERR ; | |-----------------; ADDEN ; | |------------------; CREN ; | |-------------------; SRE ; ||--------------------; RX9 ; |---------------------; SPEN movwf RCSTA ; see page 203 of Data Sheet DS39631E ; ;Timer configuration movlw b'11000110' ; ; | |--------------; T0PS0 ; | |---------------; T0PS1 ; | |----------------; T0PS2 ; | |-----------------; PSA ; | |------------------; T0SE ; | |-------------------; T0CS ; ||--------------------; T08BIT ; |---------------------; TMR0ON movwf T0CON ; see page 123 of Data Sheet DS39631E ; movlw b'10001011' ; ; | |--------------; TMR1ON ; | |---------------; TMR1CS ; | |----------------; T1SYNC- ; | |-----------------; T1OSCEN ; | |------------------; T1CKPS0 ; | |-------------------; T1CSPS1 ; ||--------------------; T1RUN ; |---------------------; RD16 movwf T1CON ; see page 127 of Data Sheet DS39631E ; movlw b'00000100' ; ; | |--------------; T2CKPS0 ; | |---------------; T2CKPS1 ; | |----------------; TMR2ON ; | |-----------------; T2OUTPS0 ; | |------------------; T2OUTPS1 ; | |-------------------; T2OUTPS2 ; ||--------------------; T2OUTPS3 ; |---------------------; - movwf T2CON ; see page 133 of Data Sheet DS39631E ; movlw b'00000000' ; ; | |--------------; TMR3ON ; | |---------------; TNR3CS ; | |----------------; T3SYNC- ; | |-----------------; T3CCP1 ; | |------------------; T3CCPS0 ; | |-------------------; T3CCPS1 ; ||--------------------; T3CCP2 ; |---------------------; RD16 movwf T3CON ; see page 135 of Data Sheet DS39631E ; ;Interrupt configuration movlw b'01110000' ; ; | |--------------; RBIF ; | |---------------; INT0IF ; | |----------------; TMR0IF ; | |-----------------; RBIE ; | |------------------; INT0IE ; | |-------------------; TMR0IE ; ||--------------------; PEIE ; |---------------------; GIE movwf INTCON ; see page 93 of Data Sheet DS39631E ; movlw b'11000000' ; ; | |--------------; RBIP ; | |---------------; - ; | |----------------; TMR0IP ; | |-----------------; - ; | |------------------; INTEDG2 ; | |-------------------; INTEDG1 ; ||--------------------; INTEDG0 ; |---------------------; RBPU- movwf INTCON2 ; see page 94 of Data Sheet DS39631E ; movlw b'00000000' ; ; | |--------------; INT1IF ; | |---------------; INT2IF ; | |----------------; - ; | |-----------------; INT1IE ; | |------------------; INT2IE ; | |-------------------; - ; ||--------------------; INT1IP ; |---------------------; INT2IP movwf INTCON3 ; see page 95 of Data Sheet DS39631E ; movlw b'00100001' ; ; | |--------------; TMR1IE ; | |---------------; TMR2IE ; | |----------------; CCP1IE ; | |-----------------; SSPIE ; | |------------------; TXIE ; | |-------------------; RCIE ; ||--------------------; ADIE ; |---------------------; PSPIE movwf PIE1 ; see page 98 of Data Sheet DS39631E ; movlw b'00000000' ; ; | |--------------; CCP2IE ; | |---------------; TMR3IE ; | |----------------; HLVDIE ; | |-----------------; BCLIE ; | |------------------; EEIE ; | |-------------------; - ; ||--------------------; CMIE ; |---------------------; OSCFIE movwf PIE2 ; see page 99 of Data Sheet DS39631E ; clrf PORTC ; clear PORTC clrf PORTD ; clear PORTD clrf PORTE ; clear PORTE ; ;Clear all user ram before start of main task. clr_ram lfsr FSR0,0x000 ; point to beginning of RAM clr_nxt clrf POSTINC0 ; clear location and inrement pointer movlw h'6' ; at top of RAM ? xorwf FSR0H,w ; check it bnz clr_nxt ; loop till top reached ; ; ;Reset all timers and clear any ourstanding interrupt requests. clrf PIR1 ; clear interrupt request reg 1 clrf PIR2 ; clear interrupt request reg 2 clrf TMR0 ; reset all timers clrf TMR1L ; clrf TMR1H ; ; ;**************************************************************************************** END ; directive 'end of program' * ;****************************************************************************************ON 20140410@4:57:15 PM at page: On a web page you were interested in at: http://www.piclist.com/Techref/piclist/weedfreq8x2LCD.htm#41738.6208101852 James Newton[JMN-EFP-786] published post 41738.6208101852 microtek@centurylink.net
Thank-you, this is a very nice patch and once I corrected my original WCT5 program with the added config statements it works great on JHD161 displays..ON 20140410@4:59:40 PM at page: On a web page you were interested in at: http://www.piclist.com/Techref/piclist/weedfreq/questions.htm#41738.626099537 James Newton[JMN-EFP-786] Published and replied to post 41738.626099537 by microtek |Insert 'I don't believe it is. If you decide to have some made, I'd be willing to go in with you on a batch purchase.' at: '' microtek@centurylink.net asks: " Is there any chance that a PC board is still available for this project?" |Delete 'P-' before: '' but after: 'Causes of low Appetite' at: '' southernskies18@gmail.com asks: " None of my fish have come up to eat for 2 days and I need to know if it is something wrong and what to do about it" |Delete 'P-' before: '' but after: 'terence_2@hotmail.com asks:
good day, your 6064 Stepper Motor Driver / breakout / cables 3 AXIS FULL KIT! $ 120.90 is already assembled and welded? already has the sink as in the picture?|Delete 'P-' before: '' but after: '
there is already an adapter cable for ramps 1.4?