concatenating 4 bytes into one pseudo 32 bit counter?


Closed Thread
Results 1 to 12 of 12

Hybrid View

  1. #1
    Join Date
    Sep 2009
    Posts
    755


    Did you find this post helpful? Yes | No

    Default Re: concatenating 4 bytes into one pseudo 32 bit counter?

    I use similar code for numbers greater then 1.
    Something like this:

    Code:
    A VAR WORD
    B,C,D,Add VAR BYTE
    INC:
    A=A+Add
    IF A>255 THEN
        A=A-255
        B=B+1
        IF B=0 THEN
          C=C+1
            IF C=0 THEN
              D=D+1
          ENDIF
        ENDIF
    ENDIF
    Last edited by pedja089; - 26th August 2011 at 14:10.

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


    Did you find this post helpful? Yes | No

    Default Re: concatenating 4 bytes into one pseudo 32 bit counter?

    Hi,
    Here's a piece of code working with a 32bit accumulator, the lookuptable from the code Hank linked to and the resulting waveform plotted in Excel with addvalues of:
    1) 512500
    2) 128500
    3) 22825

    Code:
    LSW  VAR WORD              ' Least significat word of accumulator
    MSW  VAR WORD              ' Most significatn word of accumulator
     
    ADDL VAR WORD              ' Least significant work of value to add
    ADDH VAR WORD              ' Most significant word of value to add 
     
    Out VAR BYTE                    ' This is the actual output from the lookup table
     
    Temp VAR WORD
     
    OverFlow VAR BIT             ' Gets set when 32bit accumulator overflows.
     
    i VAR WORD
     
    Init:
      LSW = 0 
      MSW = 0
      AddL = 500
      AddH = 2000   ' 50*256+500=768500
     
    Pause 3000
     
    Main:
    For i = 1 to 1000
      OverFlow = 0
      TMR1H = 0
      TMR1L = 0
     
      Gosub Add
      Gosub GetValue
     
      HSEROUT["Count: ", DEC4 i, "  MSW: ", DEC5 MSW, "   LSW: ", DEC5 LSW, "   Overflow: ", BIN Overflow, "  Out: ", DEC Out, "  Ticks: ", DEC5 TMR1H*256+TMR1L, 13]
      Pause 5
    NEXT
     
    END
     
    Add:
      T1CON = 1             ' This is just used to measure the execution time
     
      Temp = LSW            ' Remember least significant word
      LSW = LSW + ADDL      ' Add low word 
     
      If LSW < Temp Then ' Did we wrap around/overflow?
        MSW = MSW + 1       ' Increment high word
        If MSW = 0 Then OverFlow = 1  ' Did we overflow high word?
      ENDIF
     
      Temp = MSW            ' Remember high word
      MSW = MSW + ADDH      ' Add high word 
     
      If MSW < Temp Then ' Did we wrap around/overflow?
        OverFlow = 1     ' Set flag
      ENDIF
     
    T1CON = 0
    RETURN
     
    GetValue:
    Lookup MSW.HighBYTE, [$80,$83,$86,$89,$8C,$8F,$92,$95,$98,$9C,$9F,$A2,$A5,$A8,$AB,$AE,$B0,$B3,$B6,$B9,$BC,$BF,$C1,$C4,_
    $C7,$C9,$CC,$CE,$D1,$D3,$D5,$D8,$DA,$DC,$DE,$E0,$E2,$E4,$E6,$E8,$EA,$EC,$ED,$EF,$F0,$F2,$F3,$F5,$F6,$F7,$F8,$F9,$FA,$FB,$FC,$FC, _
    $FD,$FE,$FE,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$FE,$FD,$FC,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F3,$F2,$F0,$EF,$ED,$EC, _
    $EA,$E8,$E6,$E4,$E2,$E0,$DE,$DC,$DA,$D8,$D5,$D3,$D1,$CE,$CC,$C9,$C7,$C4,$C1,$BF,$BC,$B9,$B6,$B3,$B0,$AE,$AB,$A8,$A5,$A2,$9F,$9C, _
    $98,$95,$92,$8F,$8C,$89,$86,$83,$7F,$7C,$79,$76,$73,$70,$6D,$6A,$67,$63,$60,$5D,$5A,$57,$54,$51,$4F,$4C,$49,$46,$43,$40,$3E,$3B, _
    $38,$36,$33,$31,$2E,$2C,$2A,$27,$25,$23,$21,$1F,$1D,$1B,$19,$17,$15,$13,$12,$10,$0F,$0D,$0C,$0A,$09,$08,$07,$06,$05,$04,$03,$03, _
    $02,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$02,$03,$03,$04,$05,$06,$07,$08,$09,$0A,$0C,$0D,$0F,$10,$12,$13, _
    $15,$17,$19,$1B,$1D,$1F,$21,$23,$25,$27,$2A,$2C,$2E,$31,$33,$36,$38,$3B,$3E,$40,$43,$46,$49,$4C,$4F,$51,$54,$57,$5A,$5D,$60,$63, _
    $67,$6A,$6D,$70,$73,$76,$79,$7C],Out
    RETURN
    The add routine works with two words instead of four bytes and takes ~86 cycles normally but 121 cycles when it overflows. Not the most effecient code for sure but it does seem to work. If you're running at 32Mhz and interrupting at 20kHz that's still 400 cycles between interrupts.

    Name:  DDS_Excel.jpg
Views: 864
Size:  79.8 KB

    /Henrik.

  3. #3
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: concatenating 4 bytes into one pseudo 32 bit counter?

    Wow Henrik...what can I say (thank heavens for folks like you & others on here)

    I won't pretend to understand it all (once numbers start going above 256 values "woah, there goes scary stuff!").

    re this bit...

    Code:
    Init:
      LSW = 0 
      MSW = 0
    AddL = 500
    AddH = 2000   ' 50*256+500=768500
    Not understanding the bolded bits - can you please let me know what you're doing there?

    I'm trying to see how/where I would enter what in DDS terms is called the tuning word (essentially the number that gets added to the accumulator each interrupt?

    Also, I was hoping (eventually) that the tuning word would arrive serially (either being calculated manually or sent from another pic)....the maths are going to be a bit troubling...to glean the tuning word to set the required output frequency, it's

    required frequency/interrupt rate * accumulator size

    so for a wanted frequency of 4971Hz involving a 32 bit accumulator & and say an interupt rate of 20,000Hz

    (4971/20000) * 4294967296

    ...that's gonna be a challenge in an 8 bit PIC?

    Last edited by HankMcSpank; - 27th August 2011 at 00:45.

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


    Did you find this post helpful? Yes | No

    Default Re: concatenating 4 bytes into one pseudo 32 bit counter?

    Hi,
    You have the 32bit accumulator built up by the two WORDS, LSW and MSW. Then you have the 32bit value which gets added to the accumulator each iteration (each interrupt in your case) and that's the ADDL and ADDH words. Perhaps it's the invalid comment that's causing confusion....?

    Lets take a 16bit WORD as an example.
    myValue VAR WORD
    myValue = 12345

    Now, the WORD, which is two bytes holds the value 12345, if you'd look at the high byte of that word its value would be 48 and the value in the low byte would be 57. Why? Because 48*256+57=12345

    Same thing with our accumulator and "adder value" but this time we're working with two WORDS.
    ADDL = 500
    ADDH = 2000

    2000 * 65536 + 500 = 512500 which is the value getting added to the accumulator each time. In your example, 4971/20000*2^32 the, value to add the accumulator each time is 1067514121 or ADDH=16288, ADDL=64753. Or, which might be easier expressed in hex: 3FA0F909, see there's your two words, ADDH=$3FA0, ADDL=$F909

    Let me know if you try it on some real hardware.

    /Henrik.

  5. #5
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: concatenating 4 bytes into one pseudo 32 bit counter?

    Thanks Henrik....excellent stuff.

    So, using your code where I have say a 20khz interrupt rate in place, would it be the extract below that goes into the actual 'accumulator addition & lookup' interrupt subroutine?

    Code:
    Add:                            ' start of interrupt interrupt routine?
      Temp = LSW            ' Remember least significant word
      LSW = LSW + ADDL      ' Add low word 
     
      If LSW < Temp Then ' Did we wrap around/overflow?
        MSW = MSW + 1       ' Increment high word
        If MSW = 0 Then OverFlow = 1  ' Did we overflow high word?
      ENDIF
     
      Temp = MSW            ' Remember high word
      MSW = MSW + ADDH      ' Add high word 
     
      If MSW < Temp Then ' Did we wrap around/overflow?
        OverFlow = 1     ' Set flag
      ENDIF
    '
    ' 
    Lookup MSW.HighBYTE, [$80,$83,$86,$89,$8C,$8F,$92,$95,$98,$9C,$9F,$A2,$A5,$A8,$AB,$AE,$B0,$B3,$B6,$B9,$BC,$BF,$C1,$C4,_
    $C7,$C9,$CC,$CE,$D1,$D3,$D5,$D8,$DA,$DC,$DE,$E0,$E2,$E4,$E6,$E8,$EA,$EC,$ED,$EF,$F0,$F2,$F3,$F5,$F6,$F7,$F8,$F9,$FA,$FB,$FC,$FC, _
    $FD,$FE,$FE,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$FE,$FD,$FC,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F3,$F2,$F0,$EF,$ED,$EC, _
    $EA,$E8,$E6,$E4,$E2,$E0,$DE,$DC,$DA,$D8,$D5,$D3,$D1,$CE,$CC,$C9,$C7,$C4,$C1,$BF,$BC,$B9,$B6,$B3,$B0,$AE,$AB,$A8,$A5,$A2,$9F,$9C, _
    $98,$95,$92,$8F,$8C,$89,$86,$83,$7F,$7C,$79,$76,$73,$70,$6D,$6A,$67,$63,$60,$5D,$5A,$57,$54,$51,$4F,$4C,$49,$46,$43,$40,$3E,$3B, _
    $38,$36,$33,$31,$2E,$2C,$2A,$27,$25,$23,$21,$1F,$1D,$1B,$19,$17,$15,$13,$12,$10,$0F,$0D,$0C,$0A,$09,$08,$07,$06,$05,$04,$03,$03, _
    $02,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$02,$03,$03,$04,$05,$06,$07,$08,$09,$0A,$0C,$0D,$0F,$10,$12,$13, _
    $15,$17,$19,$1B,$1D,$1F,$21,$23,$25,$27,$2A,$2C,$2E,$31,$33,$36,$38,$3B,$3E,$40,$43,$46,$49,$4C,$4F,$51,$54,$57,$5A,$5D,$60,$63, _
    $67,$6A,$6D,$70,$73,$76,$79,$7C],Out
     
    @ INT_RETURN
    Last edited by HankMcSpank; - 27th August 2011 at 11:32.

  6. #6
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: concatenating 4 bytes into one pseudo 32 bit counter?

    Henrik, rather than have two threads running, if you don't mind I'll cut/paste your input over to the other thread http://www.picbasic.co.uk/forum/show...921#post106921 , which perhaps has a more appropriate title for the content we are now discussing (allowing others to find it easier)

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