Search code examples
assemblyavr

AVR Is it possible to address IO ports indirectly


I have a question:

Is it possible to address the I/O ports of the AVR controllers indirectly like:

out r16, r19

Thanks for your help


Solution

  • According to the official instruction manual, unfortunately the instructions in and out doesn't support indirect addressing. But you can use the load (ld, lds and ldd) and store (st, sts and std) instructions instead. They are usually used for I/O operations on more complex (with more peripherals) AVR micro controllers, but should work on I/O addresses lesser than 0x60 too.

    Quote from the instruction manual:

    Note: Some complex AVR Microcontrollers have more peripheral units than can be supported within the64 locations reserved in the opcode for I/O direct addressing. The extended I/O memory from address 64to 255 can only be reached by data addressing, not I/O addressing.

    These simple indirect addressing example (GNU Assembler) should work:

    /* Load DDRA I/O address into RAMPX (r26, r27) */
    clr r27;
    ldi r26, 0x21;
    /* Store value 0xFF into specific (DDRA) register */
    ldi r16, 0xFF;
    st X, r16;
    

    The above example use DDRA I/O port from an ATMEGA2560. For the correct I/O address consult the datasheet from the specific device.