Skip to main content

Interface Push Button To Atmega328 with Input Pullup

     In previous tutorial we learned how to interface a LED to Atmega328 and then wrote the code in Atmel Studio to make it go 'ON' and 'OFF' after every one second. In short we learned how to use our MCU's port pin as a simple digital output. In this tutorial we will be using a push button as an input to turn LED on for certain duration.
     Like last tutorial we will be using PORTB for our purpose. We will be using PB5(Pin 19) as output and PB1(Pin 15) as input. In this tutorial we will be using Current Sink method to interface LED with the mcu, whereas internal pullup method for interfacing the pushbutton. The following image shows the circuit we need to assemble.
Schematic for Interfacing LED and Button

What is Current Sinking?

     When the current flows from power supply to load and then to the Microcontroller's pin (or any other device) the configuration is called Current Sinking. In our circuit Power Supply is of 5V, LED is the Load and then the microntroller. Here the LED will turn ON when microcontroller's pin is set to logic LOW(0V) and turn OFF when pin is set to logic HIGH(5V).

What is Pull-up?

Think of pullup as a high voltage(5V) default value to input of the micro-controller when the button is pressed. Now you can use an external pullup, but our Atmega mcu provides facility of internal pullup which can be activated or deactivated thus helping us in avoiding the hassle of extra circuitry. In internal pullup the default value of input is set by micro-controller itself using its internal pullup circuitry.
External Pullup Circuit
Internal Pullup of MCU



      Lets move to the coding now that we know what is current sinking and internal pullup. In previous tutorial we learned how to make new project in Atmel Studio, follow hose steps again and make a new project. Include the 'io.h' and 'delay.h' libraries in the code, also define the F_CPU value which is 16000000 in our case.
     In main loop, first we need to set the data direction registers to set the mcu's pin as input or output. Here we need to set pin PB5 as output and PB1 as input. We will be using DDRB register since we are using pins of PORTB. DDRx (x = port B, C, D) is a 8-bit register. Each bit represents the physical port pin of micro-controller. Writing a bit to '1' will set the corresponding pin as OUTPUT and writing it to '0' will set the pin to input. So we will configure the DDRB in such way that PB5 will be output and PB1 will be input, but keep in mind that pins to which the crystal is connected are also on PORTB, that means those pins are multi-purpose pin. You don't want to set those 2 (PB6 and PB7) pins as output let them just be as input. Read the image below in which I have given some more explanation on writing value to DDRB.
DDRB = 0X20; //set PB5 as output and rest as input

      Now that PB1 is set as input, we need to activate internal pull-up for that pin. PB5 is to set HIGH for current sinking method. To activate internal pullup of particular port pin we need to raise the corresponding bit in register PORTx to HIGH. 
 PORTB = 0x22; //set output PORTB5 to HIGH(for current sinking method) and PORTB1 to input Pull-up
     
     After initializing PB1 and PB5 we need to move to the while loop. To make our LED glow we need to check if the button is pressed or not. 'If' statement will be used for this purpose. The condition for 'if' statement will be to check the bit that corresponds to PB1 in register PINB. A mask value will be required to check if there has been any change in the bit's value. 

while(1)//infinite loop
  {
    if((PINB & 0x02) == 0) //check if button is pressed
        {
            for(int x = 0; x<=10; x++)
            {
                PORTB = 0x02;//set PB5 to LOW while keeping internal pullup of PB1 active
                _delay_ms(100);
                PORTB = 0x22;//set PB5 to HIGH while keeping internal pullup of PB1 active
                _delay_ms(100);
            }
        }           
    }


Button & LED Interfaced to MCU
 Now that our code is complete it is time to compile it and upload he hex file to microcontroller. Hope this tutorial helps you in interfacing a push button to Atmega328!

Download Solution!

Comments

Popular Post

Generating Delay Using Timer/Counter of Atmega328

     Delay is required in most of our micro-controller applications, for example to blink a LED for certain duration or just to pause the micro-controller for short time. The avr-gcc compiler in Atmel Studio comes with delay.h library to make things easy for us, but do we know how it work. No, not until we do some digging inside of the library. In this post we will learn to generate short delay without using library, this will give some basic idea for how the  _delay_ms() or _delay_us() works.      In this tutorial a Logic Analyzer is used to observe the output of Atmega328 on pin PB5. Circuit configuration for Atmega328 is shown in diagram below. Circuit Configuration      Atmega328 has three individual timer/counters identified as TC0, TC1, TC2. TC0 is an 8 bit general purpose timer/counter which can also be used for generating PWM waves, TC1 on other hand is 16 bit timer and can be used for generating PWM. Timer/Counter 2 (TC2) is 8 bit timer with support for PWM generat