- Basics of Arduino Coding
- How to use Android Phone to write codes and upload in Arduino?
- Effective coding techniques in Arduino: More about datatypes
- Effective coding techniques in Arduino: More about variables
- How to design Cathode Ray Oscilloscope using Arduino? Code of just 9 lines!
- How to start learning NodeMCU in simple steps? Basic Tutorial on NodeMCU
- How to use array to rotate servo motor in different angles?
- Blinking LED code for Arduino in Assembly Language Programming (ALP)
- Having trouble to drive Servo motor with Arduino Uno SMD? Get perfect solution now…
A simple LED blinking program in assembly language for Arduino Uno, which uses the ATmega328 microcontroller. Note that writing assembly code for Arduino is less common, and most Arduino programs are written in higher-level languages like C++.
However, for educational purposes, here’s a basic example in ALP as given below.
.equ LED_PIN, 13 ; Define LED pin number
.org 0x0000 ; Start address
start:
ldi r16, (1<<LED_PIN) ; Load immediate value with LED pin mask
out DDRB, r16 ; Set LED pin as output
loop:
ldi r16, (1<<LED_PIN) ; Load immediate value with LED pin mask
out PORTB, r16 ; Turn on the LED
call delay ; Call delay subroutine
cbi PORTB, LED_PIN ; Turn off the LED
call delay ; Call delay subroutine
rjmp loop ; Jump back to the loop
delay:
ldi r21, 0xFF ; Outer loop counter
outer:
ldi r22, 0xFF ; Inner loop counter
inner:
dec r22 ; Decrement inner counter
brne inner ; Repeat inner loop if not zero
dec r21 ; Decrement outer counter
brne outer ; Repeat outer loop if not zero
ret ; Return from subroutine
Code Explanation
.equ LED_PIN, 13 ; Define LED pin number
This line defines a constant named LED_PIN with a value of 13. This constant is used later in the program to represent the digital pin number to which the LED is connected.
.org 0x0000 ; Start address
This line sets the origin (start address) of the program to 0x0000, indicating that the program begins at the address 0.
start:
ldi r16, (1<<LED_PIN) ; Load immediate value with LED pin mask
out DDRB, r16 ; Set LED pin as output
- start:: This label marks the beginning of the program at the start address.
- ldi r16, (1<<LED_PIN): This instruction loads the immediate value with a bitmask for the LED pin. The (1<<LED_PIN) operation sets the bit corresponding to LED_PIN in the register r16.
- out DDRB, r16: This instruction sets the LED pin as an output by writing the value in r16 to the Data Direction Register (DDRB) for Port B.
loop:
ldi r16, (1<<LED_PIN) ; Load immediate value with LED pin mask
out PORTB, r16 ; Turn on the LED
call delay ; Call delay subroutine
cbi PORTB, LED_PIN ; Turn off the LED
call delay ; Call delay subroutine
rjmp loop ; Jump back to the loop
- loop:: This label marks the beginning of the main loop.
- ldi r16, (1<<LED_PIN): Similar to the previous occurrence, this loads the immediate value with a bitmask for the LED pin into r16.
- out PORTB, r16: This instruction turns on the LED by writing the value in r16 to the Port B register (PORTB).
- call delay: This instruction calls the delay subroutine to introduce a delay.
- cbi PORTB, LED_PIN: This instruction clears the bit corresponding to the LED pin in the Port B register (PORTB), turning off the LED.
- call delay: Another call to the delay subroutine for a delay.
- rjmp loop: This instruction performs an unconditional relative jump (rjmp) back to the loop label, creating a loop that repeats the LED blinking process.
delay:
ldi r21, 0xFF ; Outer loop counter
outer:
ldi r22, 0xFF ; Inner loop counter
inner:
dec r22 ; Decrement inner counter
brne inner ; Repeat inner loop if not zero
dec r21 ; Decrement outer counter
brne outer ; Repeat outer loop if not zero
ret ; Return from subroutine
- delay:: This label marks the beginning of the delay subroutine.
- ldi r21, 0xFF: This instruction loads the outer loop counter r21 with the value 0xFF.
- outer:: This label marks the beginning of the outer loop.
- ldi r22, 0xFF: This instruction loads the inner loop counter r22 with the value 0xFF.
- inner:: This label marks the beginning of the inner loop.
- dec r22: This instruction decrements the inner loop counter.
- brne inner: This branch instruction repeats the inner loop if the inner counter is not zero.
- dec r21: This instruction decrements the outer loop counter.
- brne outer: This branch instruction repeats the outer loop if the outer counter is not zero.
- ret: This instruction is a subroutine return, indicating the end of the delay subroutine. The program returns to the point immediately after the call delay instruction in the main loop.
This assembly program creates a simple loop that blinks the LED connected to pin 13 on the Arduino Uno with a delay introduced by the delay subroutine.
The delay is produced by the nested loops using counters r21 and r22.
The outer loop creates a longer delay, and the inner loop creates a shorter delay, resulting in a visible LED blinking effect.
How to compile & upload the code in Arduino?
To compile and upload assembly code for Arduino Uno using the AVR-GCC toolchain, you’ll need to follow these step-by-step procedures. Note that this process involves using the command line, and you’ll need to have the necessary tools installed on your computer.
What you will need?
- Install AVR-GCC: Make sure you have AVR-GCC installed on your computer. You can download it as part of the AVR toolchain. Alternatively, you can use a package manager like apt (on Linux) or the official Windows installer to install AVR-GCC.
- Install AVRDUDE: AVRDUDE is a utility for programming AVR microcontrollers. Make sure it’s installed on your computer.
- Create Makefile: Create a Makefile to automate the compilation and uploading process. Here’s a simple example.
Example Code
TARGET = blink
all: $(TARGET).hex
$(TARGET).hex: $(TARGET).asm
avr-as -mmcu=atmega328p -o $(TARGET).obj $(TARGET).asm
avr-objcopy -O ihex $(TARGET).obj $(TARGET).hex
upload: $(TARGET).hex
avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 -b 115200 -U flash:w:$(TARGET).hex
clean:
rm -f $(TARGET).obj $(TARGET).hex
Remember to change the TARGET variable to match the name of your assembly file (without the extension).
Compile and Upload Steps
- Save Assembly Code: Save your LED blinking assembly code in a file, for example, blink.asm.
- Open Terminal (Command Prompt): Open a terminal or command prompt in the directory where your assembly code and Makefile are located.
- Run Make: Run the make command to compile the assembly code and generate the HEX file:
make
Upload to Arduino UNO
- Connect your Arduino Uno to your computer via USB.
- Run the following command to upload the HEX file to the Arduino Uno. Modify the port (/dev/ttyUSB0 on Linux or COMx on Windows) based on your system.
make upload
Here we assume that your Arduino Uno is using the ATmega328p microcontroller. If you are using a different Arduino model, update the -p option accordingly.
- Verify LED Blinking: After the upload is complete, you should see the LED connected to pin 13 on your Arduino Uno blinking.
- Clean Up: If needed, you can clean up the generated files using following code.
make clean
These steps provide a basic guide for compiling and uploading assembly code to an Arduino Uno using AVR-GCC and AVRDUDE. Ensure that your system recognizes the Arduino board and you have the correct drivers installed. Additionally, double-check the port and board parameters in the Makefile.
If you have queries or want more explanation please write comment below.