Professional Documents
Culture Documents
Tutorials on:
Using the AVR Studio 6 Simulator and Debugger
Input/output Ports
First we have to discuss about I/O ports. Generally AVR microcontrollers have four I/O ports named as
PORTA, PORTB, PORTC, PORTD up to PORTG (ATMEGA128). Take example as ATMEGA8 or
ATMEGA 16 or ATMEGA32 microcontrollers, these are any having four I/O ports and each port having
8 I/O lines. These lines are bi-directional means we can use these I/O lines either input or output. In
addition to each this pin has some of other functions like ADC, timers, interrupts, serial communication
pins and other pins. To perform any operation with general purpose I/O (GPIO) pins there is a need to
configure three registers. Those registers named as DDRx, PORTx, PINx (here x indicates the name of
the register A or B or C or D).
Each registers of these three registers are 8-bit registers means generally each port has 8 pins as like each
register has 8-bits and each pin refers on bit of register. If we want to configure any pin of the port we can
configure the corresponding bits of all three registers. In this article I am taking example as ATMEGA128
microcontroller. Now consider pins 35-42 of the microcontroller, if we want to configure these 8-pins,
there is a need of configure corresponding three registers of 8-bits. Here explaining clearly, in
ATMEGA128 pin 35-42 refers PORTC. So if we want to configure PORTC, we need to configure DDRC,
PORTC and PINC registers
These 8-bits are divided into two 4-bit groups and named as lower nibbles upper nibbles. 0-3 bits are
called as lower nibbles and 4-7 bits are called as upper nibbles.
This register is used to assign the pin of the port as either input direction or output direction. In
this register the port and pin indicated as DDRxn, here x indicates the port name and n
indicates the pin number. For example pin 38 refers to 4th pin of PORTC is defined as DDRC4.
Generally these GPIO pins are digital I/O pins that mean these are having only two logics as
logic0 and logic1. Same like these DDR also. If DDRxn is written as logic one, the pin is
configured as output pin. If DDRxn is written as logic zero, the pin is configured as input pin.
Up to here we are discussing as logic 0 and logic 1, but how to know what is logic 0 and what is
logic 1, how both are differs. Generally most of the microcontrollers drives the 5V, and before
setting the pin either input or output there is 5V of potential at each GPIO pin of controller.
Microcontrollers have some threshold voltage levels. The threshold level is indicated as half of
the driving voltage. If the driving voltage of controller is 5V, the threshold voltage of the
controller is 2.5V. So the controller knows that if voltage level is below the threshold level, it
sense as logic zero and above the threshold level it sense as logic one.
So in this sense logic zero means DDRxn configured as input pin and logic one means DDRxn
configured as output pin. If pin is configured as input, the internal pull-up resistors will be on. If
we want to turn-off the pull-up resistors, the pin has to be configured as output.
DDRx register
Example
To configure some bits of PORTC as inputs and some bits as outputs where configure 0,2,4,6
pins as inputs and 1,3,5,7 pins as outputs.
Solution
Generally the register initial value is zero means register bits are configured to input. So change
require bits to logic one to change as output.
Generally we are using shift operation to assign value to bit of register. Take bit0 of DDRC, the
initial value of the bit is zero. If we want to change the bit to one, just we can use simple shift
operation as 1<<DDRC0. If we want to change remaining bits, that is also same but OR
operation is performed between the bits. Now in our example the code is as follows:
DDRC = (1<<DDRC1) | (1<<DDRC3) | (1<<DDRC5) | (1<<DDRC7);
The above line indicates that setting 1,3,5,7 pins of PORTC as outputs and setting 0,2,4,6 pins of
PORTC as inputs.
There are so many ways to perform this operation mentioned below.
DDRC = (1<<1) | (1<<3) | (1<<5) | (1<<7);
Or
Or
DDRC = 0xAA;
DDRC = 0b10101010;
This register is very useful for setting output pins either low or high. DDRx register set some bits
as input bits and some as output bits. The PORTx register is very useful to set the output bits as
either high or low.
This register declaration is similar to the DDRx register, the only change is name of the register.
From the above example, let us set some of output pins as low and some of output pins as high.
Here we are setting 1, 5 pins are high and 3, 7 pins are low.
PORTD = (1<<PORTD1) | (1<<PORTD5);
Or PORTD = (1<<1) | (1<<5);
Or PORTD = 0b00100010;
Or PORTD = 0x22;
Download and install Atmel Studio by following the instructions on Atmels website. If
you use Windows Vista, you should download Atmel Studio 6.2, because that is latest
version that supports Windows Vista. This tutorial was written for Atmel Studio 7.0 and
Atmel Studio 6.2.
Install the USB AVR Programmers drivers on your computer.
If you are using Atmel Studio 6 or older, you might need to add an XML file to Atmel
Studio to make it support the AVR you wish to program.
After you have completed these prerequisites, you can create a new Atmel Studio project:
1. Open Atmel Studio and click New Project. In the New Project dialog, select GCC C
Executable Project for the template. Enter the project name and location. In this tutorial,
we will name our project BlinkLED and put it in the C:\ directory, but you can
choose a different name and location if you would like. Uncheck the Create directory
for solution box to simplify the directory structure of your project. Click OK.
3. Remove the template code that was automatically placed in BlinkLED.c and replace it
with the code below:
4. Click the Build Solution button on the toolbar (or press F7) to compile the code.
(This following part concerns you only in case you have hardware/Target
device)
Downloading and Executing Your Program
Once a program has been successfully compiled, linked, and located, it must be moved to the
target platform
Download the binary image to the embedded system
-Executable binary image is transferred and loaded into a memory device on target board
-Can be loaded into ROM via a device programmer, which burns a chip that is then re-inserted
into the embedded system.
-Your program will then execute when you reset the
processor, or apply power to the embedded system
Debugging Embedded Software
Now that the software has been downloaded to the target processor, how do we know if it is
working?
Run-time errors are not as obvious
-Most embedded systems do not have a screen
-When a program fails, usually causes the processor to crash or lock-up
Logic errors
If program runs, is it performing the correct steps?
Debugging Tools
hardware/Target)
7. This will bring up the Device Programming dialog. For the Tool, select the STK500 that
you added earlier. Select the same device you selected earlier. If your device is not in the
list, you might need to add it to the list by following the instructions. For the Interface,
select ISP. Click Apply.
Selecting a programmer, device, and interface in the Device Programming dialog of Atmel
Studio 6.
If you got an error that says Unable to connect to tool STK500 and you see an error message in
the Output pane in the main window that says The signature of the attached tool is AVRISP_2,
which is unexpected. then you need to upgrade your programmers firmware to version 1.07 or
later
If you have not done so already, connect the programmer to the target device using the 6-pin ISP
cable. Make sure the cable is oriented so that pin 1 on the connector lines up with pin 1 on your
target device, and that the target device is powered on. You can test the connection by clicking
the Read button next to the Device Signature box. This sends a command to the target AVR
asking for its signature. If everything works correctly, you should see a number in hex notation
appear in the Device Signature box. If you get an error about the signature being wrong, you
might have selected the wrong device. If you get a warning that says Read voltage is outside
selected devices operating range then double check to make sure that your device is powered
and that you have upgraded the programmer to firmware version 1.07 or later.
If there were no problems, the LED connected to PORTD1 of your AVR should now be
flashing!
It supports software emulation of any real AVR device without actually connecting it.
It gives access to all the peripherals of the real MCU but no external devices.
So if you want to give external signals, you need to do it yourself, either by manually
updating the registers.
Let us consider the following code as an example to explain the functionality of the AVR
Simulator.
1
2
3
4
5
6
7
8
9
10
11
12
#include <avr/io.h>
int main(void)
{
uint8_t counter;
DDRB = 0xFF;
while(1)
{
counter++;
// insert breakpoint here <----PORTB = counter;
}
}
Now, click on the Debug menu and then click on Start Debugging and Break. If
initially no debugger is chosen, AVR Studio 6 will ask you to choose a Debug Tool.
AVR Simulator is always an option there. Choose it and click OK.
Debug Tool
fter this, debugging starts and halts in the beginning of main(). You can see a yellow
arrow mark determining the current executing line.
Let us place a breakpoint in the main and start execution. Highlight the variable counter
in counter++, right click it, go to Breakpoint and then click on Insert Breakpoint.
Insert Breakpoint
Now press the play button (F5) or click on Continue from the Debug menu to run to the
breakpoint.
Now look at the affected registers in the I/O view. If you dont have the I/O View open,
you can select it from the Debug toolbar or from the Debug windows menu.
I/O View
All the peripheral features are mentioned over here. We can monitor any changes from
the software and also manipulate the values to provide input.
Now, since the counter changes the value of PORTB, scroll down in the I/O View and
click on PORTB.
Upon clicking PORTB, you can see the three registers assigned for PORTB operations,
PINB, DDRB and PORTB. You can also view their current values.
A solid block represents 1 whereas a blank block represents 0.
Since it the beginning of main(), we defined DDRB = 0xFF, all the blocks are filled. You
can also look at its value there.
Now, press the play button. The loop iterates once and stops at the breakpoint. You can
see that values of PINB and PORTB have changed to 0x01. This is because after one
iteration, counter = 1.
(You can use Reset and Restart to move to the starting point of debugging)
The red block indicates that there has been a change in the value of the bit. If its a solid
red block, a change has been there from 0 to 1. If its just a red outline, its the other way
round.(from 1 to 0)
Once again click on play. You will be able to see the following sequences.
Now, if you want to change some other registers (apart from the ones changed by the
code), simply click on the corresponding register and change its value.
Say for example you want to change the value of DDRD. Click on PORTD and then give
any value you want. You can also click on the corresponding bits to toggle the values.