How do I extract a set number of bits?
MJG300
Posts: 3
Hey everyone,
I am trying to write a program for the BS2px. It takes a word sized number (Ex: 8000) and break it down to bits 0 thru 6 and bits 7 thru 13. I would like to make bits 0 to 6 a seperate byte as well as bits 7 to 13.
Example: 1500 * 4 = 6000
11101110000
The reason for this is I am using the Pololu Micro Maestro 6. I am using their Compact Protocol. Bits 6 to 0 is 10000,bits 13 to 7 is 01110. By turning these into decimals, I will be able to write the commands easier. I have the Basic Stamp Syntax and Reference Manual. It talks about highbyte and lowbyte but does not talk about a specific set of bits that I give a variable name to. Any help would be appreciated.
Thanks to everyone for the help
Mark
I am trying to write a program for the BS2px. It takes a word sized number (Ex: 8000) and break it down to bits 0 thru 6 and bits 7 thru 13. I would like to make bits 0 to 6 a seperate byte as well as bits 7 to 13.
Example: 1500 * 4 = 6000
11101110000
The reason for this is I am using the Pololu Micro Maestro 6. I am using their Compact Protocol. Bits 6 to 0 is 10000,bits 13 to 7 is 01110. By turning these into decimals, I will be able to write the commands easier. I have the Basic Stamp Syntax and Reference Manual. It talks about highbyte and lowbyte but does not talk about a specific set of bits that I give a variable name to. Any help would be appreciated.
Thanks to everyone for the help
Mark
Comments
If I understand the Compact Protocol, each command packet consists of 4 bytes, each 8 bits; a command byte with bit 7 always a 1, and the three remaining bytes with bit 7 always 0, which poses a slight challenge when trying to convert a 16 bit word to two bytes consisting of 7 data bits each and forcing the 7th bit of each byte to 0.
One solution would be to take the word size value and maybe copy it to another Word so we can work on it without destroying the original value. Lets call this Word PMM6. Now create two aliases from this Word and call them PMM6High and PMM6Low:
PMM6High VAR PMM6.HIGHBYTE
PMM6Low VAR PMM6.LOWBYTE
Now do a left shift of the Word PMM6 followed by a right shift of the BYTE, PMM6Low. PMM6Low now holds bits 0-6 of your Word value with bit 7 set low. PMM6High now contains bits 7-13 of your Word value with bit 7 low.
PMM6 = PMM6 << 1
PMM6Low = PMM6Low >> 1
I hope this helps,
Hal
lowValue = PMM6 & $7F ' mask off the low 7 bits
highValue = (PMM6>>7) & $7F ' shift the next 7 bits right and mask off
To put these back together, you'd do:
PMM6 = (highValue<<7) | lowValue ' this assumes that each value is only 7 bits
I believe that Mark is trying to format a 16 bit number which is comprised of two full 8 bits to two bytes where bit 7 of each has to be 0, according to Pololu . Therefore bit 7 of the low half must become bit 0 of the upper half, that's why I shifted the entire word left once followed by a right shift of the lower half.
Hal
First off, Thanks to Hal and Mike for the feedback.
I tried what Hal suggested. It worked to a point. When I entered 1000 microseconds, the low byte was off. I tried 1250 microseconds next, but it too was off by one shift. 1500 uSec. was good as well as 2000. Here is my program.
' {$STAMP BS2px}
' {$PBASIC 2.5}
'
' This program calculates the control values of the Pololu Micro Maestro 6.
' Inputting the value in microseconds multiplied by 4 then taking bits 0 thru 6 and determining
' the decimal value for the first set. Then bits 7 thru 13 for the second set.
'
'
product VAR Word 'answer when microseconds multiplied by 4
usec VAR Word 'microseconds inputted by user
product1 VAR Word
hiProd VAR Byte
loProd VAR Byte
'
'
'
Main:
DEBUG "Enter your value in microseconds ",CR
DEBUGIN DEC usec
product = usec * 4
DEBUG DEC product,CR
product1 = product
loProd = product1.LOWBYTE
hiProd = product1.HIGHBYTE
hiProd = hiProd << 1
DEBUG DEC hiProd,CR
DEBUG BIN hiProd,CR
DEBUG DEC loProd,CR
DEBUG BIN loProd,CR
DEBUG CR
GOTO Main
loProd = product1.LOWBYTE
hiProd = product1.HIGHBYTE
hiProd = hiProd << 1
Should be ;
loProd = product1.LOWBYTE
hiProd = product1.HIGHBYTE
product1 = product1 << 1 ' Shift all 16 bits of product1 left one place, moves lo bit 7 over to hi bit 0
loProd = loProd >> 1 ' Shift the lower byte back to its original condition excep that lo bit 7 is forced to 0 as a result of the right shift
Lets check with 4000 ( input was 1000)
.........dec 4000 = bin 0000 1111 1010 0000 = product1
shift product1 left 1 = 0001 1111 0100 0000 = 8000 OK so far
.shift loProd right 1 = 0001 1111 0010 0000 = 7968 What????!!!! But wait.....
when sent to Pololu it will see 001 1111 010 0000 notice that the hi bits of each byte are not there since it uses bits 7 of data bytes as a flag
adding from the right, 32 + 128 + 256 + 512 + 1024 + 2048 = 4000
hope this clears it up
Hal