This is an old revision of the document!
The following chapter assumes that you are familiar with basic assembler operations for AVR microcontrollers. Below, we explain the most important construction elements and assembler instructions for manipulating the Arduino Uno's (figure 1) GPIOs, based on the ATmega328P microcontroller.
The Arduino Uno exposes a number of GPIOs that can serve as binary inputs and outputs, analogue inputs, and many of them provide advanced, hardware-accelerated functions, such as UART, SPI, I2C, PWM, and ADC. In fact, not all of the pins on the development board are such “general-purpose”: some of them provide specific features, while others do not: there is no internal multiplexer, so functions such as UART, I2C, SPI, PWM and ADC are bound to particular GPIOs and cannot be changed.
On the programming level, GPIO ports are grouped into 3 “ports” (figure 2), and it is how you can access them:
A bit in the port corresponds to a single GPIO pin, e.g. bit 5 (6th, zero-ordered) of PortB corresponds to GPIO D13 and is connected to the built-in LED.
Each Port has assigned three 8-bit registers:
There is a set of assembler instructions that operate on port registers, represented in table 1. Assembler-level operations are much faster than C++.
| Instruction | Description |
|---|---|
SBI | Set bit in register |
CBI | Clear bit in register |
SBIS | Skif if bit in register is set (1) |
SBIC | Skip if bit in register is clear (0) |
IN | Read hardware register to the general purpose register (R0-R31) |
OUT | Write general purpose register to the hardware register. |
A common scenario is to first set either the GPIO is input or output (using the correct DDRx register), then either set (SBI), reset (CBI), check (SBIS, SBIC), read the whole register (IN) or write the whole register (OUT).