Count Bits, Choose High or Low?


Closed Thread
Results 1 to 4 of 4
  1. #1
    Join Date
    Aug 2007
    Posts
    67

    Default Count Bits, Choose High or Low?

    Hey all. I'm trying to find a faster and more efficient way to evaluate a byte. I'll have some bits coming over a radio connection that will be either $00 or $FF. It is possible a certain bit error will result in perhaps a given byte received as: %00100000 instead of %00000000.

    I would like to be able to parse each byte, count the number of "1" bits and the number of "0" bits, and based on whichever is higher, load the variable with either %00000000 or %11111111. This will eliminate any bit errors as long as it's not more than 3 bit errors per byte.

    The only solution I've figured so far is a loop, but this process takes way too long.

    This loop takes about 160 uS at 16Mhz. I'm looking for a process that can do this in under 40 uS.

    Is here perhaps a more efficient assembly instruction I could use instead that would quickly evaluate this?

    Code:
    ErrorCheck:
    
        HighCount = 0
        LowCount = 0
        FOR i=0 TO 7                     
          n = testByte.0(i)              'binary value of a register
          IF n = 0 THEN
            LowCount = LowCount + 1
          ELSE
            HighCount = HighCount + 1
          ENDIF
        NEXT i
    
        IF HighCount >= LowCount THEN
           testByte = $FF   '255
          ELSE
          testByte = $00    'zero
         ENDIF
             
    RETURN
    Thanks!

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


    Did you find this post helpful? Yes | No

    Default

    This should take about 13us at 16Mhz.
    Code:
    BitCount  VAR BYTE BANK0
    testByte  VAR BYTE BANK0
    LoopCount VAR BYTE BANK0
    
    testByte = %00100100
    
    ASM
       MOVE?CB  8, _LoopCount     ;2  loop through 8-bits
       MOVE?CB  0, _BitCount      ;2  clear the Bit Count
    TestLoop
       ifdef BSR                  ;   for 18F's
          rrcf  _testByte, F      ;1     rotate LSB into carry
       else                       ;   for 16F's
          rrf   _testByte, F      ;1     rotate LSB into carry
       endif
       btfsc    STATUS, C         ;1  if a 1 rotated into carry
       incf     _BitCount, F      ;1    increment the Bit Count
       decfsz   _LoopCount, F     ;1  skip if rotated all bits
       goto     TestLoop          ;2  do the rest of the bits
    ENDASM
    When it's finished the number of 1's in the byte will be in BitCount.
    The number of 0's, would be 8-BitCount.
    And the testByte variable will have been destroyed.

    hth,
    DT

  3. #3
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    IF DT's routine is too complicated for you, which usually is for me, then take a look at this one.
    This should be faster then yours I guess.

    Code:
    <font color="#000000">ErrorCheck:
        HighCount = <font color="#FF0000">0
        </font>LowCount  = <font color="#FF0000">8
        </font>i         = <font color="#FF0000">0
    
        </font><font color="#000080"><b>WHILE </b></font>i &lt; <font color="#FF0000">8
              </font>n = testByte.<font color="#FF0000">0</font>[i]          <font color="#000080"><i>'Read bit.
              </i></font>LowCount  = LowCount - n   <font color="#000080"><i>'sub. bits.
              </i></font>HighCount = HighCount + n  <font color="#000080"><i>'add bits.
              </i></font>i = i + <font color="#FF0000">1                  </font><font color="#000080"><i>'incr. bit.
        </i><b>WEND
    
    
        </b></font>testByte = <font color="#FF0000">$00                    </font><font color="#000080"><i>'Assign value.
        </i><b>IF </b></font>HighCount &gt;= LowCount <font color="#000080"><b>THEN </b></font>testByte = <font color="#FF0000">$FF  </font><font color="#000080"><i>'change value if true.
             
    </i><b>RETURN
    </b></font>
    Edit: I did not understand the logic behind this statement:
    "This will eliminate any bit errors as long as it's not more than 3 bit errors per byte."
    You may cut the loop off if this is true and reduce the time into half of what it takes.

    -------------------
    Last edited by sayzer; - 2nd January 2009 at 09:22.
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  4. #4
    Join Date
    Aug 2007
    Posts
    67


    Did you find this post helpful? Yes | No

    Default

    Very much appreciated guys. That worked perfectly.

    Darrel's code wins though. Indeed, about 16uS. Sayzer's loop took about 112uS. An improvement but still not quite fast enough.

    If there was ever any question about the efficiency of assembly or the lack of efficiency of PBP, I guess we see it right here. lol.

    Anyway, that totally solves my problem - thank you both very much!

Similar Threads

  1. SERIN MIDI out of Synch?
    By jncortes in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 9th June 2009, 20:08
  2. Old and beyond help ?
    By DavidFMarks in forum mel PIC BASIC Pro
    Replies: 46
    Last Post: - 11th December 2008, 15:23
  3. Microcontroller with 2 way paging application problem
    By oneohthree in forum mel PIC BASIC Pro
    Replies: 30
    Last Post: - 20th April 2007, 17:27
  4. sample code for M25P32
    By Pedro Santos in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 9th January 2007, 02:37
  5. error on compiling
    By parker in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 16th June 2005, 14:31

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