Hex to Ascii routine wanted

Discussion in 'Embedded Systems and Microcontrollers' started by MaxHeadRoom, Dec 31, 2013.

  1. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    10,526
    2,369
    Anyone have, or know of a 16bit hex to ASCII conversion routine in assembly for the PIC18F?
    Especially if it takes advantage of the extra commands of the 18F, MUL etc.
    I have found a few out there, but most seem to have a glitch of some kind?
    Thanks.
    Max.
     
  2. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    hmm, what exactly do you want to convert?
    A 16 bit number into say "0x0123"?
     
  3. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    10,526
    2,369
    Convert to individual ASCII digits for LCD display.
    HEX 0x0156 -> ASCII (decimal 342) 33, 34, 32
    Thanks.
    Max.
     
    Last edited: Dec 31, 2013
  4. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    I never saw a PICs isnctruction set, but it basically goes like this:
    Take the highest nibble from the number (higherst 4 bits)
    if the nibble is lower than 10, then add 48 and print
    else add 55 and print
    shift the whole number left by 4 bits and repeat everything 4 times

    I am not sure if you can manipulate a whole 16bit number in one operation, so you might need to make the shift left to work with two bytes, that is usually done through a carry bit or similar.
    Do you have any goals for efficiency and speed, or does it just need to work somehow?
     
  5. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    10,526
    2,369
    I would like it as fast as possible, that is why I wanted to take advantage of the higher instruction set of the 18f.
    I may have to re-work some of the ones I have tried so far.
    Max.
     
  6. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,670
    804
    My guess is it will take roughly 20 instructions to translate the 16bit number into ascii. Don´t know how often you would use this, but I bet it is way faster than your lcd routine, and shaving a few instrucions will not matter much.
     
  7. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    While technically not a part of the standard C library, many compiler packages host a function ltoa() for long to ASCII. It mirrors the standard function atol().

    You can Google ltoa and find many examples, the the translate C to asm.

    I will not guess why you would not simply compile code to assembly.
     
  8. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    10,526
    2,369
    Once I have it I will make sure to post it! ;)
    Max.
     
  9. Lourens

    New Member

    Jul 16, 2012
    14
    1
    Hi MaxHR
    i have available two routines in pic18 asm that will convert a signed and unsigned 16bit number to their ascii representation. They are part of the library for a graphical programming IDE i call VPS_P18. Here is the code for the unsigned value conversion to give you an idea. For the signed conversion the code is longer. How do i get the source files to you?
    UINTtoASCII:
    lfsr FSR1,ApplStack ; Flush application stack
    movff POSTINC0, POSTINC1 ; Push Value on Application Stack
    movff POSTINC0, POSTINC1 ; ...
    call Word2asci ; Convert value to ASCII
    movff FSR1L,FSR0L ; FSR0 point to string start
    movff FSR1H,FSR0H ; ..
    StkAddStackPtr -2 ; Clean-up application stack
    return ;
     
  10. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    10,526
    2,369
    P.M. sent
    Max.
     
  11. John P

    AAC Fanatic!

    Oct 14, 2008
    1,634
    224
    The title says "Hex to Ascii routine wanted" but this is actually a conversion to decimal combined with output as ASCII. The decimal conversion will probably take most of the work.
     
  12. John P

    AAC Fanatic!

    Oct 14, 2008
    1,634
    224
    The title says "Hex to Ascii routine wanted" but this is actually a conversion to decimal combined with output as ASCII. The decimal conversion will most likely take most of the work.

    Coding for this may be more efficient if you know ahead of time what the range of the data can be--or is it all the way from 0x0000 to 0xFFFF?
     
  13. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    10,526
    2,369
    0x0000 to 0x1770.
    Max.
     
  14. John P

    AAC Fanatic!

    Oct 14, 2008
    1,634
    224
    So what you want isn't 16-bit conversion but 13 bits, with output 0-6000, or maybe 0-5999.

    One starting point would be to note that if the top bit is set, the thousands place is going to be 4, 5 or 6, and you could test for those.
     
  15. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    An easy way would be to mask off the bottom byte with 0b00001111 so you get a new nibble value in the range 0-15. Then use a standard computed jump table to RETLW with the ASCII value in the char range 0-9 or A-F.

    After that you do a dual-byte bit shift (two RRF instructions) done 4 times, which moves the 16bit variable to the right 4 bits and loads the next nibble. Then rinse and repeat. The whole thing should be only a handful of lines of ASM code and the 16 byte lookup table.

    A minor issue is that it outputs the 4 HEX digits starting from the LSN but that is not much of a drama you can just display the 4 characters on the LCD going from right to left.
     
    djsfantasi likes this.
  16. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    Hi Max'...

    I wonder if you're lookin' for something like this routine which produces packed BCD digits which are easily converted to ASCII? The 16-bit input is placed in the 16 bit "bin" variable (little endian format) before calling the routine and the four digit packed BCD output is located in the 16 bit "bcd" variable (little endian format) on exit. Do you know how to convert the packed BCD digits to ASCII for sending to the LCD?

    This routine is for 14-bit core devices. I have a routine for 16-bit core devices too, which is smaller/quicker. I'll post it in a subsequent post, as soon as I find it...

    Regards, Mike

    Code ( (Unknown Language)):
    1.   /********************************************************************
    2.    *  16-bit "bin" to 4-digit packed "bcd" (26 words, 340 cycles)     *
    3.    *                                                                ***/
    4.    void bin2bcd()               // destroys "bin" input
    5.    { asm clrf   _bcd+0          // clear bcd output variable
    6.      asm clrf   _bcd+1          //   "
    7.      asm movlw  0x10            //
    8.      asm movwf  _bitctr         // bitctr = 16
    9.    lp1:
    10.      asm movlw  0x33            // Mike Keitz's "bcd adj" method
    11.      asm addwf  _bcd+0,F        //
    12.      asm btfsc  _bcd+0,3        // test if lo result > 7
    13.      asm andlw  0xF0            // lo result > 7 so take the 3 out
    14.      asm btfsc  _bcd+0,7        // test if hi result > 7
    15.      asm andlw  0x0F            // hi result > 7 so ok
    16.      asm subwf  _bcd+0,F        // any results <= 7, subtract back
    17.      asm movlw  0x33            //
    18.      asm addwf  _bcd+1,F        //
    19.      asm btfsc  _bcd+1,3        // test if lo result > 7
    20.      asm andlw  0xF0            // lo result > 7 so take the 3 out
    21.      asm btfsc  _bcd+1,7        // test if hi result > 7
    22.      asm andlw  0x0F            // hi result > 7 so ok
    23.      asm subwf  _bcd+1,F        // any result <= 7, subtract back
    24.      asm rlf    _bin+0,F        // get another bit
    25.      asm rlf    _bin+1,F        //
    26.      asm rlf    _bcd+0,F        //
    27.      asm rlf    _bcd+1,F        //
    28.    //asm rlf    _bcd+2,F        // (for 5 digit output up to 65535)
    29.      asm decfsz _bitctr,F       // done? yes, skip, else
    30.      asm bra    lp1             //
    31.    }                            //
    32.  
     
    Last edited: Jan 1, 2014
  17. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    Hi Max':

    Here's a version for 18F (16 bit core) devices that's a bit smaller/faster;

    Regards, Mike

    Code ( (Unknown Language)):
    1. ;******************************************************************
    2. ;
    3. ;  Bin2Bcd 16 bit binary to 4 digit packed BCD
    4. ;
    5. ;  Number Range: 0000..270F (0000..9999)
    6. ;
    7. ;  17 words, 215 cycles (including call and return)
    8. ;
    9. BCD     equ     0x30            ; 16 bit little endian
    10. BIN     equ     0x32            ; 16 bit little endian
    11.  
    12.         radix dec
    13. Bin2Bcd
    14.         clrf    BCD+0           ; LSB..MSB
    15.         clrf    BCD+1           ;
    16.         movlw   16              ;
    17.         movwf   BitCtr          ;
    18. CnvtBit
    19.         rlcf    BIN+0,F         ; LSB..MSB
    20.         rlcf    BIN+1,F         ;
    21.         movf    BCD+0,W         ;
    22.         addwfc  BCD+0,W         ;
    23.         daw                     ;
    24.         movwf   BCD+0           ;
    25.         movf    BCD+1,W         ;
    26.         addwfc  BCD+1,W         ;
    27.         daw                     ;
    28.         movwf   BCD+1           ;
    29.         decfsz  BitCtr,F        ;
    30.         bra     CnvtBit         ;
    31.         return                  ;
    32.  
     
    Last edited: Jan 1, 2014
  18. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    10,526
    2,369
    Thanks for the inputs.
    Max.
     
  19. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    That conversion function is standard in the Microchip C8 compiler. Can not remember what they call it. And I am not sitting a computer with C8 right now. But it is in the manual
     
  20. nigelwright7557

    Senior Member

    May 10, 2008
    487
    71
    You would be better working it out for yourself.
    It really is not hard to do.
    Just work from the top nibble and convert to ascii one nibble at a time.

    If you cant do this simple task then you are going to struggle with the pic.
     
Loading...