1
\$\begingroup\$

I want to simply assign (copy) a bit in the IO register from some other register bit (or flag, or as a result of some comparison). Now I am using following (PORTD[2] := r0[3]):

    sbrc r0, 3      ; Skip if Bit in Register is Cleared
    sbi  PORTD, 2   ; Set Bit in I/O Register
    sbrs r0, 3      ; Skip if Bit in Register is Set
    cbi  PORTD, 2   ; Clear Bit in I/O Register

But is it optimal? Is there better way? How to make it with other sources - some flag for example C or T?

\$\endgroup\$
3
  • \$\begingroup\$ If it doesn't matter if the I/O-pin briefly toggles (when it is already low and it is to stay low), then you could remove the first sbrc. \$\endgroup\$
    – jippie
    Commented Nov 25, 2013 at 14:02
  • \$\begingroup\$ One trick is to write the code in C, then check if the compiler comes up with a smart trick that you didn't think of yet. \$\endgroup\$
    – jippie
    Commented Nov 25, 2013 at 14:05
  • \$\begingroup\$ @jippie, glitches in the output are not acceptable. \$\endgroup\$
    – johnfound
    Commented Nov 25, 2013 at 15:11

1 Answer 1

2
\$\begingroup\$

On many AVRs, this can be made faster (but not smaller) via the status register's T bit:

bst  r0, 3      ; Store bit 3 of r0 into T
in   r2, PORTD  ; Read the current value of PORTD
bld  r2, 2      ; Load bit 2 of r1 from T
out  PORTD, r2  ; Write the updated value back to PORTD

This requires only 4 cycles (vs. 5: either 2+0+1+2 or 1+2+2+0) and always updates PORTD at the fourth cycle regardless of the bit value.

Caveats:

  • If an ISR updates PORTD between the in and out instructions, that update will be reverted by the out.
  • Another CPU register is required if r0's value must be preserved (r2 in this example, but it can be any).
  • XMEGA and Reduced Core AVR devices have single-cycle cbi and sbi instructions, so there's no speed difference on those targets.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.