Embedded System - Arduino

 

 

 

 

I/O Register

 

The GPIO on ATmega chipset on Arduno board is controlled by a couple of Registers called I/O register (if you don't know what the register is, read Register page in Embedded System section first). It is one of the most important things that you need to know because almost every Arduino programming is to operate one or more of these I/O pins. It means regardless of whether you recognize or not, almost all of your Arduino program is manipulating one or more of these registers.

If you are intersted in writing Arduino program in C or Assembly,  you need to very clearly understand the relationship between these registers and the I/O pins connected to these registers.

If you want to know how much you already know of these registers and its operations, take a look at the section Atmega 328 GPIO Memory Map/ Register Description and ask your self 'can I write a C or Assembly program to set a specific I/O port just based on the table ?' If the answer is Yes, you don't have to ready this page any more.. if the answer is 'No', this page would be helpful for you to get some practical understanding on Arduino I/O registers.

 

If you look at the AVR Architecture (ATmega processor) diagram, you would find three I/O ports. Each of these I/O ports has 8 GPIO pins. How to you manipulate these GPIO. To figure out how to program these GPIO, you need to figure out what kind of I/O registers are controlling each of these I/O pins. In AVR microprocessor, each of these ports are connected to three different I/O registers called DDRx, PORTx, PINx. And then, each I/O pins within a port is mapped to each individual bit of the I/O registers. These mappings can be illustrated as shown below (It took me while to draw all of these wires in power point :).

 

 

 

Now let me explain the functionality of each I/O Registers. The functionality of each I/O registers is as follows :

    DDRx : DDR stands for Data Direction Register. 'x' is just a place holder for a chacter like B, C, D port. So the register name of each Port become DDRB, DDRC, DDRD. This register specifies the direction of each I/O pins connected to it. For example, if you set a specific bit in the register to be '1', the pin connected to the bit become a Output pin and if you set a specific bit in the register to be '0', the pin connected to the bit become a Input pin.

    PORTx : Each bit in this register specifies the output voltage of the pin connected to the bit.  'x' is just a place holder for a chacter like B, C, D port. So the register name of each Port become PORTB, PORTC, PORTD.  If you set a specific bit in the register to be '1', the output voltage of the pin connected to the bit become +5 V (i.e, logical value '1') and If you set a specific bit in the register to be '1', the output voltage of the pin connected to the bit become 0 V (i.e, logical value '0'). Since this defines the output votage (value) of a pin, this value become meaningful only when DDR bit for the pin is set to be '1'.

    PINx : This register is for reading the value for a specific pin connected to the register.

 

Now I think (hope) you get some general idea on how Arduino I/O Register works. For more concrete understaing on how this principle is applied in programming, let me give you a short example program written in Assembly. Don't worry if you don't know anything about Assembly, this is very short and I will put the comments for each line.

 

.equ    PORTB, 0x05 // this is like #define PORTB 0x05.This is the address of the register PORTB

.equ    DDRB, 0x04  // this is like #define DDRB  0x04.This is the address of the register DDRB

 

.org 0x0000

    jmp main

 

main:

    ldi r16,0b00100000  // this is like an assignment int r16 = 0b00100000 ('0b' mean 'binary')

    out DDRB, r16       // this mean write the value r16(0b00100000) into DDRB register

    out PORTB, r16      // this mean write the value r16(0b00100000) into PORTB register

 

// The processor keep running these two lines. It become as if the program stand still at this point

Start:    

    rjmp Start

 

 

Can you guess what would happen when you run the code above ? The result is as follows. Pin 5 in Port B is outputting 5 V( logic '1') as illustrated below.

 

 

 

Reference :

 

[1] AVR I/O Ports