...take a number in the range of 0x00 to 0xFF in W and output two ASCII characters, the most significant character into CHAR_HI and the least significant into W. No other registers can be used.
From: Scott Dattalo
movwf char_hi swapf char_hi,w andlw 0x0f addlw 6 skpndc addlw 'A'-('9'+1) addlw '0'-6 xorwf char_hi,w xorwf char_hi,f xorwf char_hi,w andlw 0x0f addlw 6 skpndc addlw 'A'-('9'+1) addlw '0'-6My resulting code is 15 cycles, isochronous
Sean H. Breheny [shb7 at CORNELL.EDU] says:
movwf CHAR_HI ; Place W in CHAR_HI to store swapf CHAR_HI,W ; Place CHAR_HI in W with most ; significant nibble in lower ; part of W andlw 0x0F ; Clear upper part of W addlw -10 ; Same as single digit, do conversion btfsc STATUS,C addlw 'A'-'0'-10 addlw '0'+10 ; Swap W and CHAR_HI xorwf CHAR_HI,F ; CHAR_HI = CHAR_HI xor W xorwf CHAR_HI,W ; W = W xor CHAR_HI xor W ; = (W xor W) xor CHAR_HI ; = 0 xor CHAR_HI = CHAR_HI xorwf CHAR_HI,F ; CHAR_HI = CHAR_HI xor W xor CHAR_HI ; = (CHAR_HI xor CHAR_HI) xor W ; = 0 xor W = W andlw 0x0F ; Now we have original W back in W ; Clear upper part so we are left ; with original least significant ; nibble addlw -10 ; Same as single digit, do conversion btfsc STATUS,C addlw 'A'-'0'-10 addlw '0'+10 ; We're done
Kübek Tony [tony.kubek at FLINTAB.COM] says:
another version: uses one stack-level more is not 'faster' but less code space :); *********************************************************************** ; ; CONV_BYTE_HEX - Converts the byte in w to two ASCII hex digits ('0'-'9', 'A'-'F' ) ; Returns with top nibble ASCII digit in char_hi and the bottom one inW ; NOTE uses TWO deep stack ( nested calls ) !! CONV_BYTE_HEX MOVWF char_hi ; save byte temporarily SWAPF char_hi,W ; convert top nibble CALL CONV_NIBBLE_HEX ; top nibble in w, exchange char_hi with w XORWF char_hi,F XORWF char_hi,W XORWF char_hi,F ; and convert low nibble CONV_NIBBLE_HEX ANDLW 0x0F ; mask out top nibble, preserv low nibble ADDLW 0xF6 ; add 246, to check if 0-9 or a-f, w=nibble+246 BTFSC STATUS,C ; if carry set then a-f ADDLW 0x07 ; carry set, then add 7, w=nibble+246+7 ( note nibble known to be a-f ) ADDLW 0x3A ; then finally add 58 to get 'proper' ascii ; 1) w = low(nibble+246+58) = 48+nibble ( if 0-9 ) ; 2) w = low(nibble+246+7+58) = 55+nibble ( if a-f ) ; nibble converted to ASCII hex in w RETURN
Comments:
A warning to users: This code is actually not usable for the range 0x00 to 0xFF, but only 0x00 to 0x99. Any nibbles of a value from 0xA to 0xF are converted to 0x3A through 0x3F, which is not correct ASCII. This code is only safe to use if your values will not go above 0x99.
Code:
After calling bin2hex, usualy data must be sended to some interface: hi-byte first than lo-byte But we get char_hi and WREG (char_lo) Better way to have char_lo and W (char_hi) So: <blockquote> bin2hex: MOVWF char_lo CALL convert_nibble XORWF char_lo,F XORWF char_lo,W XORWF char_lo,F SWAPF WREG,W convert_nibble: ANDLW 0x0F ADDLW 0xF6 BTFSC STATUS,C ADDLW 0x07 ADDLW 0x3A RETURN </blockquote>