PDA

View Full Version : Count Bits, Choose High or Low?



kevj
- 1st January 2009, 20:04
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?



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!

Darrel Taylor
- 1st January 2009, 23:44
This should take about 13us at 16Mhz.

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,

sayzer
- 2nd January 2009, 09:19
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.


<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.

-------------------

kevj
- 2nd January 2009, 19:17
Very much appreciated guys. That worked perfectly.

Darrel's code wins though. :D 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!