Reconfigurable computing
Small Embedded Systems
Unit 3.4 I/O Using Direct
Port Register Manipulation
Introduction
The Arduino library aims to hide away
The detail of what is happening
The differences between different microcontrollers
in order to make life easy for the programmer
If we want to write code that is efficient and powerful, we need to write code makes detailed use of features of the microcontroller
In these units we will look at how this would work on an ATmega 328P, which is a member of the AVR family
The same approach and thought process is necessary on any other microcontroller, but details will differ
I/O using special function registers
So far we have done input/output using Arduino library functions digitalRead() and digitalWrite()
These work by manipulating the registers that control the ports
We can get the same effect by directly manipulating port registers in our own code
This makes code harder to read and more complicated, but there are advantages in doing it this way
We will re-write our LED bink program to use the special function registers of the Atmega 328P
The Data Sheet
All microcontrollers will have a data sheet
The ATmega328P data sheet is on Canvas
It is 660 pages long, but well indexed
ATmega328P
I/O is connected to 3 ports
We are going to use Arduino pin 13
That is PORTB, pin 5
ATmega328P
I/O is connected to 3 ports
We are going to use Arduino pin 13
That is PORTB, pin 5
From Datasheet section on I/O Ports
We refer to section on I/O ports
From Datasheet section on I/O Ports
ATmega 328 I/O port B are controlled by three 8-bit registers:
PINB – input value at pins on port B
DDRB – data direction (input=0/output=1) at pins on port B
PORTB – output value at pins on port B
I/O Ports
Each port has control registers on memory map
Say we want port B’s
Pin 5 to be output
All others to be inputs
Write 0b00100000 to memory location 0x24
1 means output
0 means input
Direction – DDRB at address 0x24
Input – PINB at address 0x23
Output – PORTB at address 0x25
I/O Port Registers
This is what is happening at bit 5 of port B
To set it to an output, write 1 to DDRB bit 5
DDRB bit 5
PORTB bit 5
PINB bit 5
Data bus
IO pin on chip
This diagram is a heavily simplified summary
Disabled
1
Enabled
Issue address of DDRB 0x24 to steer data bus content to that register
I/O Port Registers
Now we want to output a HIGH to port B’s pin5
Write 0b00100000 to memory location 0x25
DDRB bit 5
PORTB bit 5
PINB bit 5
Data bus
IO pin on chip
This diagram is a heavily simplified summary
Disabled
1
Enabled
1
Issue address of PORTB 0x25 to steer data bus content to that register
1
I/O Port Manipulation in C
Suppose we want to make pins 5 and 2 output HIGH
We want to do this by direct manipulation of the registers
Any of these is OK
These can be hard to read, so often we give symbolic names to the bits to make things clearer
PORTB = PORTB | 0b00100100
PORTB |= 0b00100100
PORTB |= (1<<5) | (1<<2)
PORTB |= (1<
Arduino environment has already done
#include
so you don’t have to write this in your code
PORTB |= (1<