0% found this document useful (0 votes)
84 views

GPIO Programming

This document provides an introduction to GPIO programming on the ATmega644 microcontroller using the WinAVR development environment. It explains how to set up a basic blinking LED project, compile and upload code. It also demonstrates reading input pins and debouncing a switch. Finally, it proposes a design problem to decode a keypad and display values on a seven segment display using AVR C programming and simulating in Proteus.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
84 views

GPIO Programming

This document provides an introduction to GPIO programming on the ATmega644 microcontroller using the WinAVR development environment. It explains how to set up a basic blinking LED project, compile and upload code. It also demonstrates reading input pins and debouncing a switch. Finally, it proposes a design problem to decode a keypad and display values on a seven segment display using AVR C programming and simulating in Proteus.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

Activity 4 – Getting Stated with Embedded C-Programming – GPIO programming

Introduction
As with other microcontrollers, the first programming activity is GPIO (General Purpose Input/Output) control.
In this activity, we will be introduced with utilizing GPIO’s of ATmega644. Gizduino+ 644 will be used.

WINAVR

The latest WinAVR (as of this writing) is 2010-01-20. It is a GCC based compiler for AVR microcontrollers. It comes
with its own IDE, the Programmer’ Notepad which can be useful but users can also make use of any text editor. Unlike other
IDE’s, using WinAVR requires us to make our own makefile. Makefile is simply a script that will guide us to compile and link
out programs. WinAVR installation do come with a makefile wizard, the Mfile editor.

Hello World with AVR

#include <avr/io.h>

#define LED PB7

unsigned char i, j;
void delay(void){
for (i=0;i<255;i++) {
for (j=0;j<255;j++);
}
}

int main(void){
DDRB |= (1<<LED);
PORTB &= ~(1<<LED);
while(1){
PORTB |= (1<<LED);
delay();
PORTB &= ~(1<<LED);
delay();
}
return 0;
}

The code above is simple blinky program. LED will be connected to pin PB5 of PORTB.

1 | G e tti n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
About the code

#include <avr/io.h>
This line includes IO.Hwhich describes all definition required to simplify the coding. IO.H can be found in
“C:\WinAVR-20100110\avr\include\avr”, assuming default installation of WinAVR. Inside IO.H, the actual header
file will be pointed out depending on the device being used. In our case, it’s the ATMEGA644. ATMEGA644 should
be defined in the makefile (more on this later).

#define LED PB7


We define or name PB5 as LED. PB5 is assigned with ‘5’.
unsigned char i,j;
void delay(void){
for (i=0;i<255;i++) {
for (j=0;j<255;j++);
}
}
This function is a delay (a software delay) that we will use to sufficiently let us see the blinking of the LED.

DDRB |= (1<<LED);
This line defines the direction of a particular PIN/PORT. DDRB is PORTB Data Direction Register. Setting (1) any pin
indicates an output. And Clearing (0) it makes it an input.

The way the line written is referred to as AVR style notation. Actually, this line executes several commands. LED is
defined as the 5th pin (PB5). Therefore (1<<LED) means we shift a ‘1’ LED times. After execution, the 8-bit value
should be 0b00010000.

The “|=” is an “OR” operator in C (just like in C++).

So, the DDRB |= (1<<LED) is like DDRB = DDRB OR 0b00010000. This tells us that when we OR a particular bit/s
with ‘1’, it becomes ‘1’.

In relation to this, it is worth noting:


That when we want to make a bit HIGH, we OR it with '1'.
Example:
REG = 0b00001010;
REG = REG OR 0b11000000; // REG becomes 0b11001010.
//This can be also writen as
REG |= 0b11000000;

And when we want to make a bit LOW, we AND it with '0'.


Example:
REG = 0b11001010;
REG = REG AND 0b00111111; //REG becomes 0b00001010
//This can also be writen as
REG &= ~0b11000000; //&= is AND operator and ~ is NOT operator

PORTB &= ~(1<<LED);


We write ‘0’ to PORTB pin PB5.

while(1){
PORTB |= (1<<LED);
delay();

2 | G e tti n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
PORTB &= ~(1<<LED);
delay();
}
This foreverloop should toggle the state of the LED. Setting a pin makes it HIGH and clearing makes it LOW

Using WinAVR

 Copy-paste the code above to a text editor and save it in folder with any filename with ‘c’ extension (figure 1).
For this activity, let us call it as main.c.

Figure 1. The hello world using Notepad++ as text editor.

 Launch mfile (from Start menu). A default makefile script will be shown, save it to your working folder (the
folder where you saved the main.c).

3 | G e tti n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
Figure 2. Makefile generation on mfile.

 Go the working folder and open makefile with any text editor. And edit the following lines as:
MCU = atmega644p
F_CPU = 16000000
AVRDUDE_PROGRAMMER = Arduino
AVRDUDE_PORT = usb
Then save it.
We use 16MHz because it is the oscillator installed in the gizDuino+ 644.

Figure 3. Editing the Makefile.

4 | G e tti n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
 Open your command prompt and go to the working register and type the command “make all”.
The “make all” command compiles, links and generates output files, such as HEX, ELF and COF. We will be
needing HEX file.

Figure 4. Working folder showing the files generated after "make all".

 Connect the gizduino+ 644p on your USB port and wait for enumeration of the PL2303 USB to serial driver.
The driver can be downloaded from: http://www.prolific.com.tw/US/ShowProduct.aspx?p_id=225&pcid=41
 Connect an LED on PB7 (with a limit resistor). PB7 is PIN 13 in gizduino+. (Refer to the schematic included on
this activity)
 In the command prompt on the same folder, type “make program”. The HEX file will now be downloaded .
 An LED on PB7 should blink very fast but is noticeable.
 Note: When recompiling or using “make all”, be sure to clean it first by “make clean”. You can also make use of
an oscilloscope instead of LED to verify your code.

Using a more accurate delay

There is an incorporated delay function that comes with WinAVR. Utilizing it is simply by including it as a header.
The code below demonstrate the usage of the delay function and the inclusion of the header file.

#include <avr/io.h>
#include <util/delay.h>

#define LED PB7

int main(void)
{
DDRB |= (1<<LED);
PORTB &= ~(1<<LED);
while(1)
{
PORTB |= (1<<LED);
_delay_ms(500);
PORTB &= ~(1<<LED);
_delay_ms(500);
}
return 0;
}

5 | G e tti n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
Inputs with AVR

There are 3 Registers involving an I/O register. For PORTB, these are DDRB, PORTB and PINB. DDRD is as we know is the Data
Direction Register, PORTB is the Data Register itself and PINB is the Input register for PORTB. When we want to write to
PORTB, we write to PORTB and when we want to read PORTB, we read PINB.

The code below will show us how read a pin. PINB bit zero is to detect an active-low signal. When an active-low is detected
it shall toggle the LED connected to bit 0.

The code below shall demonstrate the usage of an I/O as input.

#include <avr/io.h>
#include <util/delay.h>

#define SWITCH PB0


#define LED PD0

int main(void)
{
DDRB &= ~(1<<SWITCH); // PB0 as input
DDRD |= (1<<LED); // bit 0 is output
PORTD = (1<<LED); // initialize LED to HIGH
while(1)
{
if(!(PINB) & (1<<SWITCH)) //detects if SWITCH is LOW
{
_delay_ms(200); // a debounce delay
PORTD ^= (1<<LED); // toggle LED
}
}
return 0;
}

The schematic blow shall demonstrate the inputting code.

6 | G e tti n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
Design Problem: Keypad decoder

Using AVR C programming, you are to decode a keypad and simulate it in Proteus. You may follow the schematic
below or assign your I/O to other pins. The program will show the number pressed on the seven segment. The
value shall not change until another key is pressed.

References:

 ATmega644 Datasheet
 AVR C Runtime Library

7 | G e tti n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g

You might also like