How to Assembly Code and Upload to Atmega328p
Accessing I/O in ATmega328P (Arduino) using Assembly and C
This projection is meant to teach how to access Digital IO pins in ATmega328P in Assembly as well as C code.
Beginner Protip 30 minutes 8,968
Things used in this project
Story
Prerequisites:
This is a continuation of the following tutorials:
ATmega328P and its Compages
The Pinout (with ports):
Zoom-In to see the Ports and the bit numbers.
Note: This project is a continuation of this content. Delight accept a look at information technology before starting this project.
Three ports, Port B, Port C, and Port D tin can be used as full general I/O pins. Port B and Port D are used as Digital I/O while Port C is used for Analog I/O. However, Port C tin can as well be used equally Digital I/O in case y'all need more I/O,
At present the digital I/O can exist made high or low by writing the corresponding bits into the port registers.
In that location are iii states of an I/O pin, Loftier, LOW , and High IMPEDANCE.
Loftier refers to logic ane and Depression refers to logic 0. While HIGH IMPEDANCE refers to the "NC (No Connexion)" land. It'southward e'er recommended not to leave any pins to be in a floating / high impedance state as it may sometimes lead to failure of design.
Thus the other pins can be pulled downward.
Expect, what's pull-down?
The ATmega328P is equipped with pull-upwardly and pull-down resistors. This means that, if they are not in use or if they're connected to a switch they can be tied to VCC or Ground to avoid the floating country.
The diagram below depicts the arrangement of how the pull-up or pull-down resistor can be used while connecting a switch.
The assembly language:
In the associates linguistic communication, certain keywords or mnemonics are used to specify the instructions that the processor needs to execute.
Few Basic Instructions of the Assembly language are listed below with the Syntax for a better understanding of the usage.
LDI – Load Immediate
Loads an 8 chip constant direct to annals xvi to 31.
LDS – Load Directly from Data Space
Loads one byte from the data infinite to a register. For parts with SRAM, the data infinite consists of the Annals File, I/O memory, and internal SRAM (and external SRAM if applicative). For parts without SRAM, the data infinite consists of the annals file simply. The EEPROM has a dissever address space.
STS – Store Direct to Information Space
Stores one byte from a Register to the data space. For parts with SRAM, the data space consists of the Annals File, I/O retention, and internal SRAM (and external SRAM if applicable). For parts without SRAM, the data space consists of the Register File only. The EEPROM has a separate address space.
IN - Load an I/O Location to Register
Loads data from the I/O Space (Ports, Timers, Configuration Registers, etc.) into
register Rd in the Register File.
OUT – Store Annals to I/O Location
Stores data from annals Rr in the Register File to I/O Infinite
(Ports, Timers, Configuration Registers, etc.).
CBI – Clear Chip in I/O Register
Clears a specified bit in an I/O Annals. This instruction operates on the lower 32
I/O Registers – addresses 0-31.
CBR – Clear $.25 in Register
Clears the specified bits in register Rd. Performs the logical AND between the
contents of register Rd and the complement of the constant mask K.The effect will be placed in register Rd.
SBI – Ready Bit in I/O Register
Sets a specified bit in an I/O Register. This instruction operates on the lower 32 I/O Registers – addresses 0-31.
SBR – Set up Bits in Annals
Sets specified bits in register Rd. Performs the logical ORI between the contents of register Rd and a constant mask K and places the result in the destination register Rd.
SBIC – Skip if Bit in I/O Register is Cleared
This didactics tests a single scrap in an I/O Register and skips the next instruction
if the flake is cleared. This pedagogy operates on the lower 32
I/O Registers – addresses 0-31.
SBRC – Skip if Flake in Register is Cleared
This instruction tests a single bit in a register and skips the next educational activity if
the chip is cleared.
SBIS – Skip if Flake in I/O Annals is Gear up
This instruction tests a unmarried bit in an I/O Register and skips the next didactics
if the bit is set. This instruction operates on the lower 32
I/O Registers – addresses 0-31.
SBRS – Skip if Bit in Annals is Set
This didactics tests a unmarried bit in a register and skips the next pedagogy if the bit is set.
RJMP – Relative Jump
Relative jump to an address within PC - 2K +i and PC + 2K (words). For AVR microcontrollers with Program memory not exceeding 4K words (8K bytes), this teaching can address the unabridged memory from every address location.
RET – Return from Subroutine
Returns from the subroutine. The return address is loaded from the STACK. The Stack Arrow uses a pre-increment scheme during RET.
; - A semicolon is used to comment in the assembly language however Arduino IDE supports "//" besides.
So that's sufficient for at present, nosotros will explore more in the upcoming projects.
So permit's get started.
Assembly Programming:
Problem statement: "There are two LEDs, one connected to PB2 and the other to PB3. A push-push button is continued to PB4. The task is to write an assembly code such that when the push is not pressed, the LED connected to PB2 glows and the LED connected to PB3 does not glow. When the button button is pressed, the LED connected to PB3 glows and the LED connected to PB2 does not glow."
I used a common cathode RGB LED for ease. The pinout is every bit follows:
First of all, we need to assign the direction of the ports, i.eastward, whether they are going to be used as INPUT or OUTPUT. So, PB2 and PB3 have to exist configured equally O/P and PB4 has to be configured every bit I/P.
The D ata D irection R egister (DDRx) is used to specify whether that pin is going to be an I/P or an O/P.
This tin be done in ii ways.
Method 1:
LDI R16, 0xEF ; 0x is to point that the following number is in Hexa
OUT DDRB, R16 ; Ready the DDR Register
In AVR Assembly, 0 in a data direction annals specifies that it's an I/P and 1 specifies that information technology's an O/P.
EF in hexadecimal is 1110 1111 in binary. Which corresponds to assigning
And then now PB4 is assigned every bit I/P and all other pins equally O/P
The statement LDI R16, $EF -> ways to load the value EF into the register R16 and the argument OUT DDRB, R16 -> ways to assign the respective direction bits that specify the I/P and O/P.
Method ii:
SBI DDRB, two ; Set PB2 every bit Output
SBI DDRB, 3 ; Set PB3 every bit Output
CBI DDRB, iv ; Set PB4 as Input
The above code does the following changes in the Information Management Annals:
The only change is that the bits other than 2, 3, and iv are non defined
Enable Pull-Up Resistor:
SBI PORTB, 4 ; Enable pull-upwardly resistor
It's of import to do and so considering when the button-push is not pressed, the input pin of the MCU volition exist left hanging which ways information technology's in the high-impedance land.
At present, let'southward check the land of the push and decide the land of the LEDs. Since we have pulled-upwardly the input, we need to connect the other end of the switch to a logic Loftier (VCC)
L2: SBIS PINB, 4 ; Skips below statement if Push-button is non pressed
RJMP L1
SBI PORTB, 2 ; Turn ON LED -> PB2 if not pressed
CBI PORTB, 3 ; Turn OFF LED -> PB3 if not pressed
SBIC PINB, four ; Skips below statement if Push-button is pressed
RJMP L2
L1: SBI PORTB, 3 ; Plough ON LED -> PB3 if pressed
CBI PORTB, 2 ; Turn OFF LED -> PB2 if pressed
RET
Working:
Subsequently jumping to SBI PORTB, 2 the consecutive statements are executed until the next jump at RJMP L2.
RET returns to the void loop ( ) of the main program and hence this code will outset from the beginning.
The east-C way: (C code)
void setup()
{
// put your setup code here, to run once:
pinMode (10, OUTPUT); // GPIO 10 every bit Output
pinMode (xi, OUTPUT); // GPIO 11 as Output
pinMode (12, INPUT); // GPIO 12 every bit Input
pinMode (12, INPUT_PULLUP); // Enable pull-up
} void loop()
{
// put your main code here, to run repeatedly:
if ( digitalRead(12) == LOW ) // Read the state of push
{ // Execute this if button-pressed
digitalWrite (x, LOW); // LED -> PB2 OFF
digitalWrite (11, HIGH); // LED -> PB3 ON
}
else
{ // Execute this if push not pressed
digitalWrite (ten, HIGH); // LED -> PB2 ON
digitalWrite (xi, Depression); // LED -> PB3 OFF
}
}
Upload your code:
In that location have to be 2 files to code in assembly language in the Arduino IDE. 1.ino file to provide the basic info to the IDE to use the assembler and one.s file which contains the assembly code.
Please annotation that the .ino file and the .due south file have to be inside the aforementioned folder with the same proper noun.
Hit compile and then hit upload.
Congratulations! 🎉
You have successfully uploaded the assembly code into your Arduino Uno!
Final Result:
Schematics
Code
Credits
Source: https://www.hackster.io/yeshvanth_muniraj/accessing-i-o-in-atmega328p-arduino-using-assembly-and-c-10e063
0 Response to "How to Assembly Code and Upload to Atmega328p"
Post a Comment