Home > Mobile >  Why does sbi cause the bit to toggle?
Why does sbi cause the bit to toggle?

Time:01-15

Consider this AVR assembly code:

blink:
  sbi   PINA, 0     ; Toggle PINA
  jmp   blink

According to the documentation, this should set bit 0 on port A, however, this code actually causes the bit to toggle.

Why is that?

CodePudding user response:

Why is that?

Because this is how it works on newer AVR devices: You can toggle a port pin by SBI-ing the PIN register. An example is ATmega88, whereas older ATmega8 just sets a bit in PIN.

Advantage is that this allows to atomically toggle a port pin, whereas the traditional IN-XOR-OUT is not atomic, slower and consumes more flash. To make it atomic, you'd have to (temporarily) disable IRQs.

Cf. for the example data sheet of ATmega48/88/168, Section 13 I/O-Ports:

13.2.2 Toggling the Pin

Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port.

CodePudding user response:

Why? Because hardware wiring will do it. Let look how IO pin is realized. one I/O pin of new ATmega chips

Here you can see logic diagram for every pin. Output value is driven by D flip-flops in PORTA register. DDRA register enable outputting value to pin. And PINA is second D flip flop in synchronizer. A read the PINA reads value from this flip-flop. As you can see write to PIN (WPx signal) is connected to multiplexor which select input signal for PORTA output flip-flop. In case writing one this mux is switched to upper signal where is connected inverted state of outputting value. Also clk pulse for PORTA flip-flop is generate. Result is that PORTA change his logical value.

sbi PINA, 0 instruction does not toggle PINA but toggle PORTA. PINA always follow signal on the pin after one CPU clock cycle.

If you want set bit 0 of the PORTA, you must use SBI PORTA, 0

More description of I/O port

  • Related