Remove Text Formatting
Loading...

+ Reply to Thread
Results 1 to 13 of 13

Thread: 32 bit math

  1. #1
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default 32 bit math

    I am writing an SNMP parser. The TRAP command requires that I show elapsed time in 'timer ticks', which are defined as 10mSec in length. I have talked my customer into accepting 1 Second updates, and I have written a 32 bit seconds counting routine (using 2-16 bit words). But now, to get timer ticks, I have to multiply this 32 bit number (actually only 25 bits will be used) by 100.

    Can someone tell me how I might do this?
    Charles Linquist

  2. #2
    Join Date
    Oct 2004
    Location
    Hangover, Germany
    Posts
    289

    Talking

    Oh,

    it is easy !

    Shift left all bits by 2 positions (= x4),
    store it to a variable X
    Shift left all bits by 3 positions (= x32),
    add it to the variable X
    Shift left all bits by 1 position (= x64),
    add it to the variable X

    X is holding the result !

    It can easily be done by small assembler-code.
    PBP 2.50C, MCS+ 3.0.0.5, MPLAB 8, MPASM 5.14, ASIX Presto, PoScope, mE mikroBasic V7.2, PICKIT2

  3. #3
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default

    Unfortunately, I'm "assembly challenged" when it comes to math. Can someone point me to a good source of information on how to accomplish what Mr. Wumpus has explained?
    Charles Linquist

  4. #4
    Join Date
    Oct 2004
    Location
    Hangover, Germany
    Posts
    289

    Talking

    IMHO:

    ;Here you must place your 32-bit-value
    AU var byte BankA ;Upper
    AH var byte BankA ;High
    AM var byte BankA ;Middle
    AL var byte BankA ;low

    ;Here the result is placed
    XU var byte BankA ;Upper
    XH var byte BankA ;High
    XM var byte BankA ;Middle
    XL var byte BankA ;low

    asm
    ;clear X
    clrf _XU
    clrf _XH
    clrf _XM
    clrf _XL
    ;shift A by 1 position left
    rlncf _AL,f
    rlcf _AM,f
    rlcf _AH,f
    rlcf _AU,f
    [repeat the shift-routine]
    ;move A to X
    movff _AU,_XU
    movff _AH,_XH
    movff _AM,_XM
    movff _AL,_XL
    [repeat the shift-routine]
    [repeat the shift-routine]
    [repeat the shift-routine]
    ;add A to X
    movf _AL,w
    addwf _XL,f ;ignore Carry
    movf _AM,w
    addwfc _XM,w
    movf _AH,w
    addwfc _XH,w
    movf _AU,w
    addwfc _XU,w
    [repeat the shift-routine]
    [repeat the add-routine]
    endasm
    PBP 2.50C, MCS+ 3.0.0.5, MPLAB 8, MPASM 5.14, ASIX Presto, PoScope, mE mikroBasic V7.2, PICKIT2

  5. #5
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default

    Thanks for the code, but when I input 0x64, I get 0x90 as an output.

    In the meantime, I try to figure it out at this end.
    Charles Linquist

  6. #6
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default

    This is what I'm using.

    If input = $64
    Output = $36

    ;-----------------------------------------------------------------

    The code:


    Mult32:

    asm
    ;clear X
    clrf _XU
    clrf _XH
    clrf _XM
    clrf _XL

    ;shift A by 1 position left

    rlncf _AL,f
    rlcf _AM,f
    rlcf _AH,f
    rlcf _AU,f

    ;[repeat the shift-routine]

    rlncf _AL,f
    rlcf _AM,f
    rlcf _AH,f
    rlcf _AU,f


    ;move A to X

    movff _AU,_XU
    movff _AH,_XH
    movff _AM,_XM
    movff _AL,_XL

    ;[repeat the shift-routine]

    rlncf _AL,f
    rlcf _AM,f
    rlcf _AH,f
    rlcf _AU,f

    ;[repeat the shift-routine]

    rlncf _AL,f
    rlcf _AM,f
    rlcf _AH,f
    rlcf _AU,f

    ;[repeat the shift-routine]

    rlncf _AL,f
    rlcf _AM,f
    rlcf _AH,f
    rlcf _AU,f


    ;add A to X

    movf _AL,w
    addwf _XL,f ;ignore Carry
    movf _AM,w
    addwfc _XM,w
    movf _AH,w
    addwfc _XH,w
    movf _AU,w
    addwfc _XU,w

    ;[repeat the shift-routine]

    rlncf _AL,f
    rlcf _AM,f
    rlcf _AH,f
    rlcf _AU,f

    ;[repeat the add-routine]

    movf _AL,w
    addwf _XL,f ;ignore Carry
    movf _AM,w
    addwfc _XM,w
    movf _AH,w
    addwfc _XH,w
    movf _AU,w
    addwfc _XU,w



    endasm
    Charles Linquist

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

    Default

    Charles,

    You have a timer running at 100 hz, and you're dividing those interrupts by 100 to count seconds. Then later you want to multiply the seconds times 100.

    Why not just count the interrupts directly? Then you have the Sec*100 already (plus fractional secs), and you can DIV32 100 that number for the seconds, or keep a separate count for the seconds and no DIV or MUL required.
    <br>
    DT

  8. #8
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default

    Darrel,

    Actually, I have 1Khz interrupt running. I really didn't want to use it because I really like routines that run often to be very short. Since this is for an SNMP trap (an ERROR has ocurred), the timer tick value will be output something like once a year. That is why I wanted to do the multiply only when necessary.

    Maybe I'm getting too stingy with the 8722's time!
    Charles Linquist

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

    Default

    OK, that sounds reasonable enough.

    So back to BigWumpus' code.

    The rlncf's are a problem because it rotates the high bit around to the low bit. What needs to be done is rotate a 0 into the Low bit, and the High bit to the carry.

    bcf STATUS, C
    rlcf _AL,f
    rlcf _AM,f
    rlcf _AH,f
    rlcf _AU,f

    and the addwfc's need to go to F (file) instead of W. Here's the corrected code...
    Code:
    asm
     
    ;clear X
        clrf _XU
        clrf _XH
        clrf _XM
        clrf _XL
    
    ;shift A by 1 position left
        bcf STATUS, C
        rlcf _AL,f
        rlcf _AM,f
        rlcf _AH,f
        rlcf _AU,f
    
    ;[repeat the shift-routine] 
    
        bcf STATUS, C
        rlcf _AL,f
        rlcf _AM,f
        rlcf _AH,f
        rlcf _AU,f
    
    
    ;move A to X
    
        movff _AU,_XU
        movff _AH,_XH
        movff _AM,_XM
        movff _AL,_XL
    
    ;[repeat the shift-routine] 
    
        bcf STATUS, C
        rlcf _AL,f
        rlcf _AM,f
        rlcf _AH,f
        rlcf _AU,f
    
    ;[repeat the shift-routine]
    
        bcf STATUS, C
        rlcf _AL,f
        rlcf _AM,f
        rlcf _AH,f
        rlcf _AU,f
    
    ;[repeat the shift-routine]
    
        bcf STATUS, C
        rlcf _AL,f
        rlcf _AM,f
        rlcf _AH,f
        rlcf _AU,f
    
    
    ;add A to X
    
        bcf STATUS, C
        movf _AL,w
        addwfc _XL,f
        movf _AM,w
        addwfc _XM,F
        movf _AH,w
        addwfc _XH,F
        movf _AU,w
        addwfc _XU,F
    
    ;[repeat the shift-routine]
    
        bcf STATUS, C
        rlcf _AL,f
        rlcf _AM,f
        rlcf _AH,f
        rlcf _AU,f
    
    ;[repeat the add-routine]
    
        bcf STATUS, C
        movf _AL,w
        addwfc _XL,f
        movf _AM,w
        addwfc _XM,F
        movf _AH,w
        addwfc _XH,F
        movf _AU,w
        addwfc _XU,F
    endasm
    Or, Here's my little spin on it.
    Code:
    gosub Mult32
    
    ;______________________________
    Mult32:
    asm
        call ShiftA
        call ShiftA      ; *4      
        movff _AU,_XU    ; move A to X
        movff _AH,_XH
        movff _AM,_XM
        movff _AL,_XL
        call ShiftA
        call ShiftA
        call ShiftA      ; *32
        call AddAX       ;add A to X
        call ShiftA      ; *64
        call AddAX       ;add A to X
        return
    ;________________________________________________    
    ShiftA               ; shift A by 1 position left
        bcf STATUS, C
        rlcf _AL,f
        rlcf _AM,f
        rlcf _AH,f
        rlcf _AU,f
        return
      
    AddAX                ; add A to X
        movf _AL,w
        addwf _XL,F      ;ignore Carry
        movf _AM,w
        addwfc _XM,F
        movf _AH,w
        addwfc _XH,F
        movf _AU,w
        addwfc _XU,F
        return
    endasm
    HTH,
    &nbsp; DT

  10. #10
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default

    Thank you Darrel,

    Your routine works as advertised. Now I can get on with the rest of the details of "SIMPLE" Network Management Protocol. HA!
    Charles Linquist

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

    Default

    And I'll defer that to BigWumpus,

    Great idea, just needed a little debugging.

    DT

  12. #12
    Join Date
    Oct 2004
    Location
    Hangover, Germany
    Posts
    289

    Default

    OK,
    look at the time of my message ... it was late !
    PBP 2.50C, MCS+ 3.0.0.5, MPLAB 8, MPASM 5.14, ASIX Presto, PoScope, mE mikroBasic V7.2, PICKIT2

  13. #13
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default

    Well thanks to you both, then!
    Charles Linquist

Similar Threads

  1. Bits, Bytes Words and Arrays
    By Melanie in forum FAQ - Frequently Asked Questions
    Replies: 24
    Last Post: - 14th June 2016, 07:55
  2. 32 bit math
    By fnovau in forum General
    Replies: 4
    Last Post: - 13th February 2008, 00:55
  3. Averaging 16 bit values without using 32 bit math
    By sirvo in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 5th October 2007, 22:18
  4. PIC18Fxx math 24 & 32 bit
    By ronsimpson in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 2nd December 2006, 13:52
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 02:07

Members who have read this thread : 1

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