AVR Input and Output

The Penguino is powered by an ATMega32A AVR Micro-controller. This is an overview of how to achieve digital input and output on the Penguino AVR.

Ports and Pins

The Penguino has 8 pins per port and four ports. Each pin on each port can be connected internally in various ways, depending on how certain registers are configured in the micro-controller software.

All pins on all ports can function as either general purpose digital I/O or have their own special purpose(s).

The available pins and ports and their extra functionality on the Penguino are as follows:

Port

Pin

Special Purpose

A

0 to 7

Analog to Digital Conversion (ADC)

B

7

SPI bus serial clock (SCK)

6

SPI bus Master Input/Slave Output (MOSI)

5

SPI bus Master Output/Slave Input (MISO)

4

SPI bus Slave Select Input (SS, inverted)

3

Analog Comparator - Negative Input (AIN1), Timer/Counter 0 Output Compare Match Output (OC0)

2

Analog Comparator - Positive Input (AIN0), External Interrupt 2 Input (INT2)

1

Timer/Counter1 External Counter Input (T1)

0

Timer/Counter0 External Counter Input (T0)

D*

7

Timer/Counter2 Output Compare Match Output (OC2)

6

Timer/Counter1 Input Capture Pin (ICP1)

5

Timer/Counter1 Output Compare A Match Output (OC1A)

4

Timer/Counter1 Output Compare B Match Output (OC1B)

3

External Interrupt 1 Input (INT1)

2

External Interrupt 0 Input (INT0)

C*

1

Two-wire Serial Bus Data Input/Output Line (SDA)

0

Two-wire Serial Bus Clock Line (SCL)

Configuring pins for their special purpose is not covered on this page.

General Purpose I/O Registers

Each pin on each port can be configured to act as a general-purpose digital I/O pin. Each port has three registers used to configure its digital I/O functionality in software. Each register holds an 8-bit number with each bit of this number corresponding to a pin on the port. e.g. bit 0 of the number in the PORTA register refers to the first pin on the physical port A of the device.

The registers are (where x denotes the port letter A to D):

Examples

C-code (avr-gcc) for setting ports:

DDRA = 0xFF;  // Configure all pins on port A as output (all bits set to 1)
PORTA = 0xFF; // Set all pins on port A to be a sourcing voltage (set to high)

PORTA = 0x00; // Set all pins on port A to be grounded (set to low)
PORTA = PORTA | 4;   // Set pin 2 (the third pin, as 4 in binary is 100) to high

DDRB = 0xF0;  // Configure the first 4 pins as input, the last 4 pins as output
PORTB = 0x00; // Make the first 4 pins floating (as they're inputs), the last 4 pins set to low

int x = PINB & 4; // x will be 1 if the third pin (4 in binary is 100) is sensed as high

PORTx Register for Inputs

When a pin is set as an input (in the DDRx register), it can be operating in two input modes:

floating inputs:

If the pin's bit in the PORTx register is 0, then the pin won't be connected anywhere except to the sensing/reading internal circuitry. If the pin is not connected to anything in the external circuitry, this pin's value (PINx register) will fluctuate randomly from environmental noise. If it is grounded, the pin will have the value 0, if it's connected to the operating voltage, it will have the value 1.

pulled-up inputs:

If the pins bit in the PORTx register is 1, then the pin will be connected to Vcc (the operating voltage) via an internal resistor (pull-up resistor). This means that the default value for the pin, when not connected to anything is high (1). In order to change the value, the pin must be grounded to set the value low (0). This is especially convenient for connecting to switching devices (push-buttons, etc.).

In Summary

Output bit n on port x:

Floating input bit n on port x:

Pull-up input bit n on port x:

Example Program

Imagine LEDs connected to pin 0 and 1 of port B, and a button on pin 2

leds will start with one off, one on and will alternate, until the button is pressed when they will synchronise and flash together.

   1 #include <avr/io.h>
   2 #include <util/delay.h>
   3 
   4 #define PIN0 1
   5 #define PIN1 2
   6 #define PIN2 4
   7 
   8 int main(void) {
   9         DDRB &= ~PIN2; // set pin 2 to be an input
  10         DDRB |= PIN0 | PIN1; // set pin 0 and 1 to be outputs
  11 
  12         
  13         PORTB = PIN2; // set pin 2 to be a pull-up, set everything else to 0 (outputs are low)
  14 
  15         PORTB |= PIN1; // set pin 1 to high (turn led on)
  16 
  17         // while pin 2 of port B is high (button hasn't been pressed)
  18         while ( PINB & PIN2 ) {
  19            PORTB ^= PIN0 | PIN1; // flip the bits (toggle leds on/off)
  20            _delay_ms( 500 ); // busy wait for a bit
  21         }
  22 
  23         // button pressed
  24         PORTB |= PIN0 | PIN1; // turn both leds on
  25 
  26         // forever
  27         while ( 1 ) {
  28            PORTB ^= PIN0 | PIN1; // flip the bits (toggle leds on/off)
  29            _delay_ms( 500 ); // busy wait for a bit
  30         }
  31 
  32         return 0;
  33 }

Documentation/PenguinoAVR/AVR/Digital IO (last edited 2009-10-24 04:39:49 by DavidCollien)