This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How can I exchange two bits?

The following does not work (ACC is always 0, despite out[0] is 255):

ACC0 = out[0] & 1 == 1 ? 1 : 0;
ACC1 = out[0] & 2 == 2 ? 1 : 0;
out[0] &= 0xFC;
send_string(" acc1");
send_byte(ACC);
if (ACC0)
out[0] |= 2;
if (ACC1)
out[0] |= 1;

  • I can't help but think you are assuming that you can utilize the ACCumulator from C, which of course you can, but it is extremely ill-advised to do so. "ACC" is an SFR defined in regxx.h for the microcontroller's accumulator register -- the single most frequently used register! To assume that ACC contains anything predictable after a call to send_string() is sheer lunacy. In this case, it may happen to always be zero if only because (and this is a pure guess on my part) send_string() may return after encountering the NUL-terminator of the string you are passing it and having checked for zero using the accumulator before returning.

  • Well, for starters, do you really want to do this...

    ACC0 = out[0] & 1 == 1 ? 1 : 0;
    

    ...?
    Surely the order of precedence means that you will perform the operations in this order...

    ACC0 = (255 & (1==1))?1:0
    = (255 & 1)?1:0
    = 1?1:0
    = 1

    ...or am I being daft?

    Similarly ACC1 will equal 1...

    ACC1 = (255 & (2==2))?1:0
    = (255 & 1)?1:0
    = 1?1:0
    = 1

    Don't know where you get...

    send_byte(ACC);
    

    ..your variable ACC from, you haven't said, so I can't really say why...


    ACC is always 0


    ...does this help though?

    Yours,


    Rich.

  • PS Is something up with the source code highlighting stuff?

    It was highlighted in the preview, but not in the final post!

  • Well, there's the straightforward way:

    bit temp;
    
    // save bit 0
    temp = out[0] & 1;
    
    // bit 0 = bit 1
    out[0] &= ~1;
    out[0] |= (out[0] & 2) ? 1 : 0;
    
    // bit 1 = temp
    out[0] &= ~2;
    out[0] |= temp ? 2 : 0;
    
    

    You could also use a shift instead of the conditional to get bit 1 to bit 0.

    // bit 0 = bit 1
    out[0] |= (out[0] >> 1) & 1;

    Or you could use the bit-addressable memory if you have a byte to spare in this function.

    bit tempBit;
    
    // temporary swap area
    bdata temp;
    sbit temp0 = temp^0;
    sbit temp1 = temp^1;
    
    temp = out[0];
    
    tempBit = temp0;
    temp0 = temp1;
    temp1 = tempBit;
    
    out[0] = temp;
    

    If you don't care about the other bits in out[0], you could save the use of tempBit. Or, you could use the old XOR swap trick on the bit variables:

    temp0 = temp0 ^ temp1;
    temp1 = temp0 ^ temp1;
    temp0 = temp0 ^ temp1;
    

    I haven't compiled any of these to see what the generated code might look like.

  • Thank you, I've solved it this way:

    temp1 = out[0] & 0xFC;
    switch (out[0] & 3) {
    case 1: out[0] = temp1 | 2; break;
    case 2: out[0] = temp1 | 1;
    };