Shop OBEX P1 Docs P2 Docs Learn Events
Is it possible to compare bits? — Parallax Forums

Is it possible to compare bits?

markaericmarkaeric Posts: 282
edited 2009-02-27 05:17 in General Discussion
Hello,

I've been working on a little program where I am putting various bit data into the same variable (to save space), and then trying to compare them.

Apparently the sx-key assembler did not like the following piece of code, or others like it:

cje encbits.0, encbits.1, encAcountAddTwo

what I was hoping to accomplish with the above line was to compare bit 0 and bit 1 from variable 'encbits', then jump to the label 'encAcountAddTwo' if they were the same.

Any suggestions as to the options that I have? confused.gif

Thanks,
Mark

Comments

  • ZootZoot Posts: 2,227
    edited 2009-02-24 23:13
    You can't compare bits per se. In SX/B you could do this as simple IF/THEN. In ASM you need to do something like this (alternatively, you could do mask work; really depends on final needs):

    
    ' compare tmp1.5 and tmp2.2
    MOV W, #0 ' clear W
    SNB tmp1.5 ' if tmp1.5 = 1 then...
    OR W, #%01 ' set bit 0 of W
    SNB tmp2.2  ' if tmp2.2 = 1 then...
    OR W, #%10 ' set bit 1 of W
    
    ' so now you've got a 2 bit number in W; if it's 0, no bits set, if 2 both bits set, etc.
    ' obviously there are a million variations you could do here, just remember you can
    ' OR and AND and XOR literals onto W but not ADD literals
    
    ' this would set W to 0 unless both bits are set (this is an AND), 1 otherwise
    
    ' compare tmp1.5 and tmp2.2
    MOV W, #1 ' presume both set
    SB tmp1.5 ' if tmp1.5 = 0 then...
    MOV W, #0 ' clear W
    SB tmp2.2  ' if tmp2.2 = 0 then...
    MOV W, #0 ' clear W
    JZ :neitherbit
    :bothbits
      ' do something
       JMP :done
    :neitherbit
      ' do something
    :done
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • ZootZoot Posts: 2,227
    edited 2009-02-24 23:18
    Or this.... this only works if it's two adjacent bits (or bits with same index)....

    ' compare myByte.0 and myByte.1
    MOV W, >>myByte ' get bit1 into bit0 in W
    XOR W, myByte ' now XOR with orig. bit0 in myByte; if they are different, bit0 = 1
    AND W, #%0000_0001 ' but mask off the other irrelevant bits in W
    JZ :notdifferent ' if 0, they are same as last time
    :different
       'do something
       JMP :done
    :notdifferent
       ' do something
    :done
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-02-24 23:18
    If the bitpositions are 1 apart, as in this case,

    mov w,>>encbits· 'mov b1 into b0 of w
    xor w,encbits····· 'compare with b0 of encbits
    and w,#1·········· 'extract bit, zero if equal
    snz
    jmp encAcountAddTwo


    regards peter
  • markaericmarkaeric Posts: 282
    edited 2009-02-24 23:59
    Thanks for the responses!

    Whew, it looks like it's going to be a bit tricky, as I am using cje, cjne, and cja quite a lot! This is my first attempt at writing a program in assembly, so i'm sure there is a more efficient way I could do things. I suppose I could try doing some trickery with masks, but I wonder if that's truly the best way to go. Also, currently all the bits I'm comparing with one another are not necessarily next to each other, perhaps I could rearrange them.

    Yikes! Just reviewing my code, I noticed a large omission, so perhaps I just need to rewrite the entire program with these concepts in mind [noparse]:([/noparse]

    I suppose I could just write it in C or basic (neither of which I'm proficient in though), but then I won't get the strange pleasure obtained from the challenge of assembly.
  • BeanBean Posts: 8,129
    edited 2009-02-25 00:56
    Here is what SX/B generates:

      CLR __PARAM1                   ;  IF tempb1 = tempb2 THEN Start
      ADDB __PARAM1,tempb1          
      ADDB __PARAM1,tempb2          
      JNB __PARAM1.0,@Start         
    

    · It's not pretty, but it works.

    Bean


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...

    ·
  • markaericmarkaeric Posts: 282
    edited 2009-02-25 01:26
    Is the following code ugly? lol

    I ended up creating a new variable 'TestBits' which I will reuse throughout the program. I will just move the desired bits into it, then just compare the entire byte value which I have full control of. By my logic, if encbits 0 and 1 are both zero, then when I test them against 0, if the statement is true, it will jump to the appropriate label. Same thing if they're both 1, then I just compare the 'testbits' variable with 3. Is this really inefficient?

    A_1_CngStateSub ;Sub for calculating Enc_A_count var if Enc A ch.1 changed state
    clr TestBits
    movb testbits.0, encbits.0
    movb testbits.1, encbits.1
    cje testbits, #0, :encAcountAdd
    cje testbits, #3, :encAcountAdd

    :encAcountSub
    dec Enc_A_count
    jmp :End_A1_cngState

    :encAcountAdd
    inc Enc_A_count

    :End_A1_cngState
    ret
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-02-25 02:01
    Bean's code does what you want, albeit a tiny bit more efficiently. Using your vars:

    Encoder:
      CLR   testBits
      ADDB  testBits, encBits.0
      ADDB  testBits, encBits.1
      JNB   testBits.0, :encAcountAdd
    
    :encAcountSub
      DEC   Enc_A_count
      SKIP
    
    :encAcountAdd
      INC   Enc_A_count
    
    :End_A1_cngState
      RET
    


    This works because if both bits are 0 or 1 tempBits.0 will be 0.

    [noparse][[/noparse]Edit] The jump out of encAcountSub is jumping over one instruction (INC) so SKIP can be used.

    Post Edited (JonnyMac) : 2/25/2009 4:34:08 AM GMT
  • markaericmarkaeric Posts: 282
    edited 2009-02-25 03:24
    Ohhhhhhh! I see what's happening now! I didn't even remember the addb instruction, and I certainly would not have thought of JNB testBits.0, :encAcountAdd

    Thanks for the help, everyone!
  • markaericmarkaeric Posts: 282
    edited 2009-02-26 04:19
    While this next question isn't exactly related to my original one, it is related to my project, and I didn't really want to start a new thread. Hopefully someone can enlighten me.


    I'm considering interfacing a device such as a "transmissive photomicrosensor" by omron. Looking at datasheets for various models, it's confusing me, so I want someone to give me some insight as to whether I'm on the right track, or not. If not, what am I missing?

    http://www.components.omron.com/components/web/pdflib.nsf/0/0ADB48765B0912AD85257201007DD5D8/$file/24_sx1035_0607.pdf

    There's a tiny usage schematic on the bottom right of page two. It shows a resistor attached to the emitter leg, which I presume is to limit the current through the device. But trying to interpret the info in the table labeled "Electrical and optical characteristics" is leaving me at a total loss. I don't understand what the value and condition column.

    I'm looking to apply +5v at the collector. Am I correct at interpreting max current at 20ma? So using ohms law, my load resistor should be somewhere above 250ohms, right? Am I the only one who thinks that datasheet totally sucks?
  • BeanBean Posts: 8,129
    edited 2009-02-26 12:31
    Madcows,
    · The load resistor simply converts the varying current into a varying voltage that you can detect.

    · The Rise/Fall time table shows a load resistor of 100 ohms. And the Responce time chart shows that the load can be up to 10K.

    · You will probably have to experiment with different values to get the voltage levels you want out (this will depend you the amount of current you put through the LED).

    · The datasheet looks pretty standard to me. They never give you want you "really" want to know.

    P.S. Yes, you should have started a new thread...No biggie...

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...

    ·
  • David BaylissDavid Bayliss Posts: 58
    edited 2009-02-26 14:01
    I don't know how important performance is; but for this particular case there is a slightly faster solution (single word instructions/no jumps or skips) if you don't mind trashing w:

    · mov· w, >>encBits
    ··xor · w, encBits
    · and· w,#1
    · add· enc_a_count,w
    · add· enc_a_count,w
    · dec· enc_a_count

    David


    JonnyMac said...
    Bean's code does what you want, albeit a tiny bit more efficiently. Using your vars:

    Encoder:
      CLR   testBits
      ADDB  testBits, encBits.0
      ADDB  testBits, encBits.1
      JNB   testBits.0, :encAcountAdd
    
    :encAcountSub
      DEC   Enc_A_count
      SKIP
    
    :encAcountAdd
      INC   Enc_A_count
    
    :End_A1_cngState
      RET
    


    This works because if both bits are 0 or 1 tempBits.0 will be 0.

    [noparse][[/noparse]Edit] The jump out of encAcountSub is jumping over one instruction (INC) so SKIP can be used.
  • BeanBean Posts: 8,129
    edited 2009-02-26 14:51
    David,
    NICE... Elegant solution.. Only 6 instructions.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...

    ·
  • markaericmarkaeric Posts: 282
    edited 2009-02-27 00:10
    David Bayliss said...
    I don't know how important performance is; but for this particular case there is a slightly faster solution (single word instructions/no jumps or skips) if you don't mind trashing w:

    mov w, >>encBits
    xor w, encBits
    and w,#1
    add enc_a_count,w
    add enc_a_count,w
    dec enc_a_count

    David

    Wow! It took me a second to try to figure out why you were adding w twice, then performing a subtraction. Finally, zoot's version makes sense to me too! I don't know how some of your brains figure this stuff out! This certainly helped expand my mind on sx assembly, and logic.

    Thanks,
    Mark S
  • David BaylissDavid Bayliss Posts: 58
    edited 2009-02-27 01:15
    Two decades as a compiler writer does odd things to your brain; I dream about this sort of stuff freaked.gif

    Actually, I missed a trick too ... now 5 words

    ·mov w,<<encbits
    ·xor w,encbits
    ·and w,#2
    ·add enc_a_count,w
    ·dec enc_a_count

    Same idea as before but accumulate the result in bit 1; allows the double add to be done in one instruction ...



    David
    madcows said...
    David Bayliss said...
    I don't know how important performance is; but for this particular case there is a slightly faster solution (single word instructions/no jumps or skips) if you don't mind trashing w:

    mov w, >>encBits
    xor w, encBits
    and w,#1
    add enc_a_count,w
    add enc_a_count,w
    dec enc_a_count

    David

    Wow! It took me a second to try to figure out why you were adding w twice, then performing a subtraction. Finally, zoot's version makes sense to me too! I don't know how some of your brains figure this stuff out! This certainly helped expand my mind on sx assembly, and logic.

    Thanks,
    Mark S
  • markaericmarkaeric Posts: 282
    edited 2009-02-27 05:17
    Thanks Bean....

    Ok.. does this sound right to you?:

    IL (14ma) is the current that will be sunk through RL (and whatever the next circuit sinks), and IF (20ma) is the total amount of current the detector circuit uses.



    Mark
Sign In or Register to comment.