Signed 32bit to ASCII?


Closed Thread
Results 1 to 5 of 5
  1. #1
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604

    Default Signed 32bit to ASCII?

    Hello everyone,
    I'm looking for a routine to convert a signed 32-bit variable to an ASCII string in order to send it out to a terminal or LCD. I know this is supported with PBPL but I can't afford the overhead PBPL introduces and so far I've managed to get the few 32bit operations (add & subtract) I need working without using PBPL. But now I'm a bit stuck....

    Basically I have my 32bit variable declared as two word variables, myVarH and myVarL and I have 30byte array, TxBuffer, that I'm using to send things out thru the USART.

    Anyone's got a suitable routine in your "toolbox" that you're willing to share? There are some over at the PICList and I'll try to digest them and get one of them working with PBP but I'd really like to cut some corners here if it's already been done.

    TIA
    /Henrik.

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hi Henrik,

    I didn't have anything already made, but using N-Bit_Math it only took an hour or so to write and test.

    The Main program just sets 4 different values and calls Signed32: to display them
    You can use the MOVE? macros to put your value in the Value32 variable.

    Code:
    PRECISION  CON 4 SYSTEM         ' 4 bytes = 32-bit
    INCLUDE "N-Bit_MATH.pbp"
    
    Value32  VAR BYTE[PRECISION]
    Divisor  VAR BYTE[PRECISION]
    Temp32   VAR BYTE[PRECISION]
    B32      VAR BYTE[PRECISION]
    W1       VAR WORD
    Sign     VAR BIT
    
    HSEROUT ["Ready-Set-Go",13,10]
    
    
    Main:
        @  MOVE?CP  -2147483648, _Value32
        GOSUB Signed32 : HSEROUT [13,10]
        
        @  MOVE?CP  2147483647, _Value32
        GOSUB Signed32 : HSEROUT [13,10]
    
        @  MOVE?CP  1234, _Value32
        GOSUB Signed32 : HSEROUT [13,10]
    
        @  MOVE?CP  -1234, _Value32
        GOSUB Signed32 : HSEROUT [13,10]
    STOP
    
    ;----[Send signed 32-bit value via USART]---------------------------------------------------
    Signed32:
        @  MATH_CLR _Temp32                           ; clear Temp32 in case we need ABS
        Sign = Value32.0(31)                          ; If the value is negative
        IF Sign THEN
            HSEROUT ["-"]                             ; display a negative sign
            @  MATH_SUB  _Temp32, _Value32, _Temp32   ; get the absolute value (0-value)
        ELSE
            @  MOVE?PP   _Value32, _Temp32
        ENDIF
    
        @  MOVE?CP  1000000, _Divisor
        @  MATH_DIV  _Temp32, _Divisor, _B32          ; divide by 1,000,000 gets top 4 digits
        @  MOVE?PW   _B32, _W1                        ; copy digits to PBP word var
    ;    @  MATH_MUL  _B32, _Divisor, _B32             ; multiply those digits by 1,000,000
    ;    @  MATH_SUB  _Temp32, _B32, _Temp32           ; subtract from original value
    
        @  MOVE?CP   1000, _Divisor                   ; divide remainder by 1,000
        @  MATH_DIV  REG_Z, _Divisor, _B32            ; 3 digits are in B32, 3 digits in REG_Z
    
        IF W1 > 0 THEN                                ; W1 still has top 4 digits
            HSEROUT [DEC W1]                          ; if top 4 are > 0, display them
            @  MOVE?PW  _B32, _W1                     ; display next 3 digits (with 0's)
            HSEROUT [DEC3 W1]
            @  MOVE?PW  REG_Z, _W1                    ; display lowest 3 digits (with 0's)
            HSEROUT [DEC3 W1]
        ELSE                                          ; else - top 4 digits are 0
            @  MOVE?PW  _B32, _W1                     ; check next 3 digits
            IF W1 > 0 THEN                            ; if > 0 then display (without 0's)
                HSEROUT [DEC W1]
                @  MOVE?PW  REG_Z, _W1                ; display lowest 3 digits (with 0's)
                HSEROUT [DEC3 W1]
            ELSE                                      ; else - Top 7 digits are 0
                @  MOVE?PW  REG_Z, _W1                ; display lowest 3 (without 0's)
                HSEROUT [DEC W1]
            ENDIF
        ENDIF
    RETURN
    This is the output from the test program.



    It could probably benefit from a little optimization, but it works.
    HTH,
    Last edited by Darrel Taylor; - 5th May 2010 at 22:47. Reason: Some optimization - red=changed, blue=removed
    DT

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hi again Henrik,

    Not sure if you've seen the code above yet, but I've done a bit more optimization to it.

    By mapping word vars to the low word of the 32-bit vars, there's a lot less moving around of values to do between Pvars and PBP word vars.

    Here's how it looks now ...
    Code:
    PRECISION  CON 4 SYSTEM         ' 4 bytes = 32-bit
    INCLUDE "N-Bit_MATH.pbp"
    
    Value32     VAR BYTE[PRECISION]
    Temp32      VAR BYTE[PRECISION]
    Divisor     VAR BYTE[PRECISION]
    
    ;---Map Word variables onto Low Word of 32-bit variables]----------------------------------
    Value32_LW  VAR WORD EXT : @Value32_LW = _Value32
    Temp32_LW   VAR WORD EXT : @Temp32_LW = _Temp32
    REG_Z_LW    VAR WORD EXT : @REG_Z_LW = REG_Z
    W1          VAR WORD
    
    HSEROUT ["Ready-Set-Go",13,10]
    
    Main:
        @  MOVE?CP  -2147483648, _Value32
        GOSUB Signed32 : HSEROUT [13,10]
        
        @  MOVE?CP  2147483647, _Value32
        GOSUB Signed32 : HSEROUT [13,10]
    
        @  MOVE?CP  1234, _Value32
        GOSUB Signed32 : HSEROUT [13,10]
    
        @  MOVE?CP  -1234, _Value32
        GOSUB Signed32 : HSEROUT [13,10]
    
        @  MOVE?CP  10, _Value32
        GOSUB Signed32 : HSEROUT [13,10]
    STOP
    
    ;----[Send signed 32-bit value via USART]---------------------------------------------------
    Signed32:
        IF Value32.0(31) THEN                               ; If the value is negative
            HSEROUT ["-"]                                   ;   display a negative sign
            @  MATH_CLR  _Temp32                            ;   clear Temp32 for ABS
            @  MATH_SUB  _Temp32, _Value32, _Temp32         ;   get the absolute value (0-value)
        ELSE                                                ; else - value is already positive
            @  MOVE?PP   _Value32, _Temp32                  ;   copy it to Temp var
        ENDIF
    
        @  MOVE?CP  1000000, _Divisor
        @  MATH_DIV  _Temp32, _Divisor, _Temp32             ; divide by 1,000,000 gets top 4 digits
        @  MOVE?PW   _Temp32, _W1                           ; copy digits to PBP word var
        @  MOVE?CP   1000, _Divisor                         ; divide remainder by 1,000
        @  MATH_DIV  REG_Z, _Divisor, _Temp32               ; 3 digits are in Temp32, 3 digits in REG_Z
    
        IF W1 > 0 THEN                                      ; if top 4 are > 0
            HSEROUT [DEC W1, DEC3 Temp32_LW, DEC3 REG_Z_LW] ;   display all 7-10 digits
        ELSE                                                ; else - top 4 digits are 0
            IF Temp32_LW > 0 THEN                           ;   check next 3 digits    
                HSEROUT [DEC Temp32_LW, DEC3 REG_Z_LW]      ;   if > 0 then display 4-6 digits
            ELSE                                            ; else - Top 7 digits are 0
                HSEROUT [DEC REG_Z_LW]                      ;   display lowest 3 
            ENDIF
        ENDIF
    RETURN
    The output is identical to the previous post. (+10)

    HTH,
    DT

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default

    Hi Darrel,
    Sorry for the late reply. I did see it and I really appreciate the help - as usual. I was hoping someone had something already - not that someone would spend the time writing it for me....it makes me feel I owe you more than I already do...

    With that said, I'm not currently using N-bit_Math in may project. As I've only needed add and subtract I've been using the routines I adapted from the PICList and it's been working perfectly so I've had no need to change it. Apparently though this ASCII conversion was harder than I initially thought. If changing over my other 32-bit operations to N-bit_math in order to get the ASCII conversion going is the easiest way to go forward than I'll need to take it into consideration.

    Any idea of the execution time?

    Thanks again Darrel, I really appreciate all your work!

    /Henrik.

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HenrikOlsson View Post
    If changing over my other 32-bit operations to N-bit_math in order to get the ASCII conversion going is the easiest way to go forward than I'll need to take it into consideration.
    I see no reason to change what you have if it works already.

    In post#1 you indicated the value was in myVarH and myVarL.
    If you changed those word variables so they are mapped to Value32, you could display your existing values with very little modification. Just GOSUB Signed32.

    Code:
    myVarH  VAR WORD EXT : @myVarH = _Value32 + 2
    myVarL  VAR WORD EXT : @myVarL = _Value32


    Any idea of the execution time?
    No, I could run some tests in the SIM though.
    I'll get back on that.
    DT

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts