You are on page 1of 9

Experiment No.

2
Push Button Interfacing with AVR

Objective
• To make a single pin of Microcontroller as input
• To make a single pin of microcontroller as output
• To learn the push button and LED interfacing

Introduction
Push Button Interfacing
A very simple and easy way to provide for human interaction with the microcontroller is to insert
a button into the circuit. We communicate with computers using two main input devices: the mouse
and the keyboard. A keyboard is nothing more than a bunch of buttons laid-out to allow the user
to input (ASCII) characters to the computer. If you're scratching your head on the ASCII part, don't
worry--it just represents the code for each character.

Adding a button or switch to the circuit enables the microcontroller to receive human input. Other
forms of input for microcontrollers include (but are not limited to) a keyboard or a mouse, buttons,
switches, audio (through microphones), touch screen displays and digitizers. There are of course
many other devices that can provide input to a microcontroller, but these may not all be activated
by voluntary human action. I place these other devices into the "sensing" category, as these devices
typically sense conditions or events and react accordingly. A few such examples include sensors
for tilt (accelerometers), detecting infrared energy or monitoring temperature.

So, here's the skinny on buttons and mechanical switches: they're imperfect! The two families of
mechanics and electronics go together like the Montagues and Capulets. That is, they don't! When
you push a button, you might expect a clean response electronically. Well, sorry to be the bearer
of bad news, but the signal often bounces quite a bit before it settles to its correct voltage level. In
this image this phenomenon is shown.
Fig.1 Push button.

Fig.2 Push button bouncing and debouncing.

If you have inserted a capacitor between the two pins, this will smooth out the signal. Another way
we could alleviate this problem is to add a time delay into the program, just after the
microcontroller senses the first button press event. However, adding a discrete component to a
circuit to solve such an electronics problem, is often a better way than adding code to cause a
delay--as that code will introduce another potential source of a bug into the program, and will also
require more processor time to execute. In additional, this code can also result in the development
of other problems as the rest of the code continues to execute.

But what value of capacitor should we select? This will ultimately depend on how poorly the
button performs regarding this particular problem. Some buttons can display a tremendous
bouncing behavior, yet others will have very little. A low capacitor value like 1.0nF (nano-farads)
will react very quickly, with little or no effect on the bouncing. Conversely, a higher capacitor
value such as 220nF (which is still pretty small in terms of capacitors) will provide a slow transition
from the starting to the ending voltage (i.e. 5v to 0v). The transition seen with a 220nF capacity is
still pretty fast in a real-world sense however, and thus can be used on poorly performing buttons.

Now, lets move to the programming of ATmega32 microcontroller (or other MCU that you may
be applying to this experiment) to make use of the new button? Well it's really quite
straightforward! We only have to add two initializing lines just prior to the infinite loop, and a
single condition block within the loop. The two initialization lines added before the loop include
one statement to set PINB1 for input by assigning it a "0" like this:

DDRB &= ~(1 << PINB1);

We will also set pin B1 "high," meaning the pin will read 5 volts until the button is pressed; at
which time the pin will read zero volts. To set the pin at a high voltage of 5 volts, we add this line
of code:

PORTB |= 1 << PINB1;

Within the program, there must be a decision: a decision to run some code when the button is
pressed, or run some other code if the button is not pressed. This task is in the form of a conditional
statement called an "if else" statement. It does EXACTLY what is says. Just like the English
equivalent... if (the button is pressed), jump up and down, else stand on your head. The action
"jump up and down" will happen while the button is pressed. But while the button is not pressed,
the other action "stand on your head" will happen. The if statement code

if (bit_is_clear(PINB, 1));

specifies a test for a condition specified inside the parentheses. The name "bit_is_clear" represents
a function that takes two arguments. In this case the first argument is PINB, which describes the
set of pins we are specifying. The second argument represents which pin we are checking, and in
this case we are concerned with pin #1 in the set.

You might be wondering what sorts of things can we put into the code block controlled by the "if"
condition? That all depends on what you want your program (and circuit) to do. In this case, as a
way to show that this button does something and works, I have the LED blinking slowly (every
100 ms) while the button is not pressed, and blinking faster (every 10ms) while pressed.

Here are the changes made to the previous LED blinking program:
Proteus Simulation and Code

#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB = DDRB | (1 << PINB0); // make pin B.0 as output
DDRB &= ~(1 << PINB1); // make pin B.1 as input
PORTB |= 1 << PINB1; // make pin B.1 HIGH

while (1)
{
PORTB ^= 1 << PINB0;
if (PINB & 0b00000010 )
{
_delay_ms(10); //Fast
}
else
{
_delay_ms(100); //Slow, from previous
}
}
}

Fig.3 Proteus Simulation.

Code for blinking LED with push button in the presence of external clock
#ifndef F_CPU
#define F_CPU 16000000UL //clock speed is 16MHz
#endif
#include <avr/io.h>
#include <util/delay.h>
int main(void) //main starts
{
DDRD = DDRD | ( 1<<4) ; //Make pin 4 of port D as a output
DDRC = DDRC & ~(1<<5) ; // Make pin 5 of port C as a input
while (1) //initialize while loop
{
if(PINC & (1<<5) ) //if PIN5 of port C is high
{
PORTD = PORTD | ( 1<<4) ; //PIN4 of port D is high
}
else //otherwise
{
PORTD = PORTD & ~( 1<<4) ; //PIN4 of port D will remain low
}
} // while loop ends
} //main end

Fig.4 Proteus Simulation with external clock.


LED blinking one by one
#ifndef F_CPU
#define F_CPU 1000000UL //clock speed is 16MHz
#endif
#include <avr/io.h>
#include <util/delay.h>
int main(void) //main starts
{
DDRD = 0b11111111; // declaring port D as output
while(1) // initialize infinite while loop
{
PORTD = 0b10000000; // pin 0 of port D set HIGH
_delay_ms(100); // delay of one second
PORTD = 0b01000000; // pin 1 of port D set HIGH
_delay_ms(100); // delay of one second
PORTD = 0b00100000; // pin 2 of port D set HIGH
_delay_ms(100); // delay of one second
PORTD = 0b00010000; // pin 3 of port D set HIGH
_delay_ms(100); // delay of one second
PORTD = 0b00001000; // pin 4 of port D set HIGH
_delay_ms(100); // delay of one second
PORTD = 0b00000100; // pin 5 of port D set HIGH
_delay_ms(100); // delay of one second
PORTD = 0b00000010; // pin 6 of port D set HIGH
_delay_ms(000); // delay of one second
PORTD = 0b0000001; // pin 7 of port D set HIGH
_delay_ms(100); // delay of one second
} // while loop end
} //main end

Fig.5 Proteus Simulation for blinking LEDs one by one.


LAB SESSION
Lab Task
Build the circuits discussed above on breadboard and also run the simulation on Proteus.

Equipment and Materials


ATmega32
• LEDs • Connecting Wires
• Resistors • DC power supply
• Capacitors • Switch
• Crystal Oscillator

Experimental Procedure
• Connect the burner using the supplied cable (serial cable) to program the ATmega32
microcontroller.
• Connect the LEDs, switch and resistors to the appropriate PORT and build the circuit as
desired.
• Connect the microcontroller with 5V DC power supply.

Observations and Calculations


PORT used as input PORT used as output Clock Frequency used

Questions
1. What do you understand by the term bouncing and debouncing of push buttons?

2. Write down two debouncing strategies.

3. What do you understand by the term polling?

4. In Fig.3, what will you do in order to set the initial voltage on pinB1 to zero volts? How
will it affect the schematic?

5. In Fig.3, in order to run the same initial conditions, how will it change the if condition?
Lab Task
Microcontroller based digital calculator

Microcontroller based digital calculator has two inputs A and B. You may use any port or pins of
your choice. Both input A and B should operate on numbers in a range 0 to 7. Your calculator
should be able to perform Addition, Subtraction and Multiplication operations. The operations are
controlled by OP input. This input is of 2-bit width. The result of computation is displayed on any
port (pins) of your choice. Calculate how much bits are required for keeping the result and
displaying it before further proceeding.

Requirements:

• Make the complete block diagram of the system indicating input/outputs. (10)
• Make a circuit of your complete design by indicating discrete components. (10)
• Perform the simulation in software (Atmel studio + Proteus ISIS), attach printed
screenshots of successful simulations. (20)
• Write down the codes in your lab report (No typed code will be accepted). (30)
• Use of optimized hardware resources like Pins, Ports, Memory etc is encouraged. (10)

Bonus:
A reset/clear button can be added to the existing system. By pressing that pushbutton, the system
will again go the ‘ready’ state and will take new inputs. (20)

Submission:

• Perform all simulations/hardware implementation before next lab.


• Submit the report of this task before next lab.
LAB REPORT

Discussion of Results

Q1: Write the code for buglar alarm, run its simulation on Proteus and also build the hardware.

Q2: Write the code for blinking LEDs one by one with the help of a push button, run its Proteus
simulation and also build its hardware.

Conclusion / Summary

You might also like