Configuring the ATtiny2313 Pins as Inputs

Created on: 13 February 2013

Part 4 of the ATtiny2313 Tutorial

How to configure the ATtiny2313 pins as inputs. This part of the ATtiny2313 course shows how to connect a switch and LED to the ATtiny2313 microcontroller. The pin connected to the switch is configured as an input pin. The state of the switch is then read on the pin and the LED switched on or off, depending on the state of the switch.

The input pin is configured to use the internal pull-up resistor of the microcontroller. The internal pull-up resistor is then switched off and and external pull-up resistor is used.

Interfacing a Switch to a Microcontroller Pin

When a switch is interfaced to a microcontroller pin, a pull-up resistor is needed on the microcontroller pin so that the pin is pulled to a logic 1 state. Without the pull up resistor, the pin is said to be "floating" and the logic state is unknown (when floating it could be high or low, or switching between high and low as it picks up interference).

The switch is wired between the microcontroller pin and GND (0V) of the power supply. When the switch is closed, it will connect the microcontroller pin to GND which will put a logic 0 (low) on the microcontroller pin.

When software is used to read the state of the pin that the switch is interfaced to, it will read high (logic 1) when the switch is open because of the pull-up resistor. When the switch is closed, it will read a low (logic 0) because the switch is connecting it to GND.

Circuit Diagram – Using Internal Pull-up Resistor

Many modern microcontrollers, including the ATtiny2313, have internal pull-up resistors on their pins that can be enabled and disabled in software.

The circuit diagram below shows how to interface a switch to an ATtiny2313 microcontroller pin when enabling the internal pull-up resistor in software. The C program to configure the pin as an input and enable the internal pull-up resistor follows.

Interfacing a switch to an ATtiny2313 microcontroller, using internal pull-up resistor
Interfacing a Switch to an ATtiny2313 Microcontroller Pin, Using Internal Pull-up Resistor - click for a bigger image

C Program Enabling Input Pin and Internal Pull-up Resistor

The C program listing below enables the pin connected to the LED as an output. It then enables the pin connected to the switch as an input and enables the internal pull-up resistor on this pin.

The program continuously reads the state of the switch. If the switch is closed, the LED is switched on. If the switch is opened, the LED is switched off.

#include <avr/io.h>

int main(void)
{
    // output pin
    DDRD |= (1 << PD6);     // LED on pin 11 (PD6)
    // input pin
    DDRD &= ~(1 << PD5);    // switch on pin 9 (PD5)
    PORTD |= (1 << PD5);    // enable pull-up resistor
    
    while(1)
    {
        if (PIND & (1 << PD5)) {    // is switch open?
            PORTD &= ~(1 << PD6);   // switch is open, switch LED off
        }
        else {
            PORTD |= (1 << PD6);    // switch is closed, switch LED on
        }           
    }
}

Circuit Diagram – Using External Pull-up Resistor

The circuit shown below uses an external 10k pull-up resistor (R3) on the pin that the switch is interfaced to. In this case, the internal pull-up resistor on this pin can be disabled.

An external pull-up resistor can be used if the internal pull-up resistor is not strong enough and the pin is picking up interference and causing glitches.

Interfacing a Switch to an ATtiny2313 Microcontroller, Using External pull-up resistor
Interfacing a Switch to an ATtiny2313 Microcontroller Pin, Using External Pull-up Resistor - click for a bigger image

C Program Disabling Internal Pull-up Resistor

The C source code below is exactly the same as the previous code listing, except that the internal pull-up resistor on the pin that is interfaced to the switch is now disabled.

#include <avr/io.h>

int main(void)
{
    // output pin
    DDRD |= (1 << PD6);     // LED on pin 11 (PD6)
    // input pin
    DDRD &= ~(1 << PD5);    // switch on pin 9 (PD5)
    PORTD &= ~(1 << PD5);   // disable pull-up resistor
    
    while(1)
    {
        if (PIND & (1 << PD5)) {    // is switch open?
            PORTD &= ~(1 << PD6);   // switch is open, switch LED off
        }
        else {
            PORTD |= (1 << PD6);    // switch is closed, switch LED on
        }           
    }
}

ATtiny2313 Input Pin Configuration and Control Registers

Configuring a Pin as Input

The DDR register is used to configure a pin as input by writing a 0 to the corresponding bit. In the source listings above, the PD5 bit is cleared (0 is written to it) in the DDRD register (port D DDR register) using this line of code:

DDRD &= ~(1 << PD5);    // switch on pin 9 (PD5)

The comment here means that the switch is interfaced to pin 9 (PD5) and does not mean that pin 9 is switched on.

If a 1 was written to this bit, then the pin would be configured as an output.

Enabling and Disabling Internal Pull-up Resistors

The PORT register is used to enable and disable internal pull-up resistors. When a bit is set in the PORT register, the corresponding pin has its pull-up resistor enabled (1 enables the pull-up). Clearing the bit disables the pull-up (0 disables the pull-up). In the code listings above, the PORTD register is used to enable or disable the pull-up on the PD5 pin:

PORTD |= (1 << PD5);    // enable pull-up resistor
PORTD &= ~(1 << PD5);   // disable pull-up resistor

If this pin was enabled as an input, then writing to the corresponding bit in the PORT register would drive the pin high (if writing 1) or low (if writing 0).

Reading the Input Pin State

The state of a pin that is set up as an input pin can be read by reading the state of the corresponding bit in the PIN register.

In the code listings above, the PIND register is read and the PD5 bit in this register is checked to see if it is high or low:

if (PIND & (1 << PD5)) {    // is switch open?

In our example, when the switch is open, a 1 is read in the PD5 bit of the PIND register because the pin that the switch is interfaced to is pulled up by a resistor (so is high or 1). When the switch is closed, a 0 will be read (the switch pulls the pin to ground, so a low or 0 is read).

Atmel Studio Source Code

The Atmel Studio project for the above code listings can be downloaded here. It includes the C source file and hex output file as well as all the Atmel Studio files.

The source code contains both the lines of code for enabling and disabling the internal pull-up resistor. The line of code for enabling the internal pull-up has been commented out, so the source code has been compiled for use with an external pull-up (the hex file is configured to disable the pull-up). Just comment out the disable line of code and uncomment the enable line of code before compiling to change this.

read_switch.zip (13.6kB)