I am currently in an introductory assembly language class. My assignment is to use a sparkfun joystick shield kit to do something with an arduino uno. I figure turning on LEDs is the easiest. We must program it in AVR assembly(note: we have only used nasm assembly all semester).

I don't really know how this needs to be done, but I would like the lights to turn on when a button is pressed (one LED per button). I also want to use the analog pins to have the joystick LEDs fade in and out.

below is the code I have right now, and don't have the equipment to test it.

Am I on the right track, or is it a horrible mess? The professor was referring to the arduino pins with hex, but I couldn't find a mapping of the pins and their hex values.

Thanks in advance.

.include "/usr/local/include/atmega32u4.def"

        .global  main

        .section .text


        cbi     PortD, 2            ; joystick button
        cbi     PortD, 3            ; right button
        cbi     PortD, 4            ; up button
        cbi     PortD, 5            ; down button
        cbi     PortD, 6            ; left button

        cbi     PortC, 0            ; joystick vertical output
        cbi     PortC, 1            ; joystick horizontal output

        ldi     r16, 0x7c           ; select pins 2-6 for button input mask
        in      ddrd, r16           ; set digital button pins as input
        ldi     r17, 0x03           ; select pins 0 & 1 for joystick input
        in      ddrc, r17           ; set analog joystick pins as input

        ldi     r18, 0x1f           ; select pins 8-12 for button LED output
        out     ddrb, r18           ; set digital button LED pins as output
        ldi     r18, 0x0c           ; select pins 2 & 3 for joystick LED ouput
        out     ddrc, r18           ; set analog joystick LED pins as output


        ldi     r20, PortD          ; read in from digital pins 0-7
        and     r20, r16            ; apply button input mask
        mov     r20, r20 >> 2       ; shift left twice
        sts     PortB, r20          ; turn on LEDs of pushed buttons

        ldi     r20, PortC          ; read in from analog pins
        and     r20, r17            ; apply joystick input mask
        mov     r20, r20 >> 2       ; shift left twice
        sts     PortC, r20          ; turn on LEDs of joystick movement
        rjmp    loop
  • "The professor was referring to the arduino pins with hex..." I'm not sure that I understand what this means... Commented Dec 8, 2014 at 4:36
  • PORTD and PORTC are the input registers. There is no point in clearing (cbi) them. Do you have external pull-up/pull-down resistors? As for the joystick; your just reading the digital value (0/1), not the analog (0..1023). You also need to use PWM to output different brightnesses. For readability I'd probably use sbi ddrb, ddb0; set PB0 to output. That way you don't have to use unreadable hex values. It also makes changing pin assignments a lot easier. It also saves a register. Though I now see your using it as a mask to set all leds at once (nice trick).
    – Gerben
    Commented Dec 8, 2014 at 16:43
  • The professor was referring to the arduino pins with hex, but I couldn't find a mapping of the pins and their hex values - Well let's say you need to affect pin 10, in hex that would be 0A.
    – Nick Gammon
    Commented Jul 25, 2015 at 7:57
  • mov r20, r20 >> 2 ; shift left twice - looks like shift right twice to me, but whatever.
    – Nick Gammon
    Commented Jul 25, 2015 at 7:58
  • 1
    .include "/usr/local/include/atmega32u4.def" - the Uno uses the Atmega328P processor, so this is not the right file to include.
    – Nick Gammon
    Commented Aug 24, 2015 at 7:30

1 Answer 1


Did you know that the Arduino Uno uses the Atmel ATmega328P processor?

using the ADC for analog input in assembly language

You may want to skim through Chapter "24. Analog-to-Digital Converter" of the ATmega328P datasheet.

You may want to read application note "AVR126: ADC of megaAVR in Single Ended Mode" and browse through the corresponding AVR126 example software. (It's in the C language, but it mentions all the registers you'll need to read the ADC in your assembly language program). (As you can tell from the ATmega328 datasheet, the ATmega88 has exactly the same ADC as the ATmega328).

"Assembler source code for the conversion of an analogue voltage to an 8-bit-number", "AVR ASM Introduction: A moron's guide to ADC" and "ATmega8 ADC Example" have a pure assembly language program for reading the ADC on a Atmel AVR chip -- alas, on a slightly different chip that may have slightly different registers than the ATmega328P.

Good luck!

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.