Unleash the Power of AVR Hardware: Build Your Own Calculator with Keypad Input

In this lab, we will be preparing our AVR microcontroller hardware for initial programming and debugging.

To get started, follow these steps:

Construct the circuit as shown on your breadboard. This will allow us to interface our microcontroller with external components.
For reference on pin connections and specifications, consult the microcontroller’s datasheet. The datasheet is an essential reference for understanding the technical aspects of the chip. I recommend taking some time to explore the datasheet and familiarize yourself with its organization and contents. Having a working knowledge of the datasheet will serve you well as you progress through your microcontroller exploration this quarter.

By building the recommended circuit, we set the stage to begin programming our physical AVR device. Referring to the datasheet is important to properly connect components according to the microcontroller’s specifications.

All resistances are 330 Ohms.

Step 2 is to configure your AVR for use for the first time. Open AVR Studio and start a new project following the protocol given in lab 1. Build the following code:


#include “avr/io.h”


int main() {

DDRA = 0xFF;

while(1) {




Once the code above successfully compiles, select Tools->Program AVR->Connect to bring up the dialog box below. Ensure the below options are selected, and that your programmer is plugged into your machine via USB cable.

Click connect in the above dialog, and the below dialog should pop up.  Ensure that the ATMega32 device is selected, and that ISP programming mode is selected.

Click the “Board” tab and change the ISP frequency to 125 kHz. Then click “Write”.

Click the “Fuses” tab. Select “Int. RC Osc 8 MHz: 6 CK + 64ms” and ensure “JTAG Interface Enabled” is unchecked. Click “Program”.

Click the “Lockbits” tab and confirm “Mode 1” is selected for all options.

Go back to the main dialog page by clicking the “Program” tab.

Under the “FLASH” memory section, click the ellipses and select the .hex file built with your project, typically found in project_dir/default.

Click “Program” to transfer the code to the microcontroller for the first time.

Check your breadboard – you should now see some lights indicating the microcontroller is running your programmed code.

By configuring these options and programming the microcontroller, you’ve successfully interfaced with the physical device for the first time.

Part 2

You will design and build a simple 4-function calculator using a microcontroller and keypad input.

Your design must follow the state machine format provided in the lab instructions. A large portion of your grade depends on using this structure correctly.

Before writing any code, take time to fully design the state machine on paper. Embedded system design is the focus of this course.

Users will enter two numbers and select an operator (A-D) using the keypad. The output is displayed on LEDs.

Numbers are verified on the LEDs before/after selection of the operator and second number.

Pressing ‘#’ calculates and displays the result.

The lab will provide details on using a 4×4 keypad for input. Keys are detected by outputting a column pin low and reading the rows to detect button presses.

Follow all directions closely and design carefully before coding to succeed in this milestone lab. Proper planning is key.

Below is the start of a function that you should use to get input from the keyboard.  You will need to complete the function.  The function would be most helpful if it returned an index into the following conversion table.


/* You can have a conversion table to convert the key position into a

valid number which indicates the operator or operand value. For eg:

the numbers 0 to 9 are valid operands and 100 to 103 denote

addition, subtraction, multiplication and division respectively */


/* Note that your keypad has a different layout then the one used to

design this lab, thus you will need to edit the conversion table to

reflect your own keypad layout.*/


char conv_table[] =


1, 2, 3, 100 /* add */,

4, 5, 6, 101 /* sub */,

7, 8, 9, 102 /* mul */,

1, 0, 1, 103 /* div */



int GetKey( ) {

for(i=0; i<4; i++) { /* Set one column at a time to 0. */

PORTC = 0xff & ~(1<<i);

for (j=4; j<8; j++) { /* Scan each row to see if a button was pressed */

/* Use i and j to index into conversion table */




PORT/PIN Registers (PORT is for writing! PIN is for reading!)

When writing an output value to a port, use the PORT register.

For example, to write value x to Port C as output, use: PORTC = x

When reading an input value from a port, use the PIN register.

The PIN register reflects the real-time voltage level on the physical pins.

The PORT register only returns the last value written by the software. It does not account for any external hardware changes to the pin voltages.

For example, to read an input into variable x from Port D, use: x = PIND

This captures the current level on the Port D pins, accounting for both software outputs and external circuit connections.

Understanding when to use PORT vs PIN is important for proper microcontroller interfacing with external hardware via input and output operations.

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top