AVR Peripherals: General-Purpose Input/Output

READING

The AVR Microcontroller and Embedded Systems using Assembly and C
by Muhammad Ali Mazidi, Sarmad Naimi, and Sepehr Naimi

Sections: 4.1, 4.2, 6.4

SOURCE MATERIAL

1. ATmega328P Datasheet Section 13 “I/O-Ports” http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf
2. Arduino Port Registers
3. arduino-duemilanove-schematic
4. arduino-proto-shield

Table of Contents

Source: ATmega328P Data Sheet http://www.atmel.com/dyn/resources/prod_documents/8161S.pdf page 5 ******

ATMEGA GENERAL PURPOSE DIGITAL I/O PORTS

  • The ATmega328P has 23 General Purpose Digital I/O Pins assigned to 3 GPIO Ports (8-bit Ports B, D and 7-bit Port C)
  • Each I/O port pin may be configured as an output with symmetrical drive characteristics. Each pin driver is strong enough (20 mA) to drive LED displays directly.
  • Each I/O port pin may be configured as an input with or without a pull-up resistors. The values for the pull up resistors can range from 20 – 50 K ohms.
  • Each I/O pin has clamping diodes to protect input circuit from undervoltage/overvoltage and ESD conditions.

Figure 2: GPIO Schematic

DUAL ROLE OF PORTS B, C AND D OF THE ATMEGA328P

Figure 3: ATmega328P Pinout

I/O Ports B (PB7:0), Port C (PC5:0), and Port D (PD7:0)

Ports B, C, and D are bi-directional I/O ports with internal pull-up resistors (selected for each bit). The Port output buffers have symmetrical drive characteristics with both high sink and source capability.

Interrupts (INT1, INT0, PCINT23..0)

External Interrupts are triggered by the INT0 and INT1 pins or any of the PCINT23..0 pins. Observe that, if enabled, the interrupts will trigger even if the INT0 and INT1 or PCINT23..0 pins are configured as outputs. This feature provides a way of generating a software interrupt.

AVCC

AVCC is the supply voltage pin for the A/D Converter. It should be externally connected to VCC. If the ADC is used, it should be connected to VCC through a low-pass filter.

AREF

AREF is the analog reference pin for the A/D Converter.

ADC5:0

These pins serve as analog inputs to the A/D converter. These pins are powered from the analog supply and serve as 10-bit ADC channels.

I/O PORT PIN AS AN OUTPUT

  • To configure a Port (x) pin as an output set corresponding bit (n) in the Data Direction Register (DDxn) to 1. Once configured as an output pin, you control the state of the pin (1 or 0) by writing to the corresponding bit (n) of the PORTxn register.
  • Writing (signal WPx) a logic one to PINxn toggles the value of PORTxn, independent on the value of DDxn. Note that the SBI instruction can be used to toggle one single bit in a port.

Figure 4: Schematic to Implement I/O Port as an Output

I/O PORT PIN AS AN INPUT

  • To configure a Port (x) pin as an input set corresponding bit (n) in the Data Direction Register (DDxn) to 0. To add a pull-up resistor set the corresponding bit (n) of the PORTxn register to 1 (see illustration).
  • You can now read the state of the input pin by reading the corresponding bit (n) of the PINxn register.

Figure 5: Schematic to Implement I/O Port as an Input

ACCESSING GPIO LINES IN ASSEMBLY

Figure 6: CSULB Shield

DESIGN EXAMPLE 1 – Read Switches

Problem: Program GPIO Port C bits 5 to 0 as inputs with pull-up resistors. Read GPIO Port C into register r6 and move bit 4 to register r7 bit 0. Your program should not modify Port C bits 7 and 6.

Figure 7: Table for I/O Port as an Input

; Initialize Switches with Pull-up resistors

in r16, DDRC // Port C DDR for switches 5 to 0
cbr r16,0b00111111 // define bits 5 to 0 as input (clear)
out DDRC,r16 // output DDxn = 0 PORTxn = Undefined

in r16,PORTC // PORT C Register for switches 5 to 0
sbr r16,0b00111111 // add pull-up resistors (PUR)
out PORTC,r16 // output DDxn = 0 PORTxn = 1

Main:

:
in r6,PINC // R6 <- IO[0x06]
bst r6,4 // T <- R6 bit 4
bld r7,0 // R7 bit 0 (seg_a) <- T

Figure 8: 7-Segment Display Corresponding to the Four Room Switches

DESIGN EXAMPLE 2 – CONFIGURE D FLIP-FLOP

Problem: Program GPIO Port D bit 5 as an output and bit 2 as an input without a pull-up resistor.

Figure 9: Schematic of DigitalPin 2 as Input and DigitalPin 5 as Output


Table 1: GPIO

; Pushbutton debounce port D pins
.EQU dff_clk=PORTD5 // clock of debounce flip-flop
.EQU dff_Q=PIND2 // Q output of debounce flip-flop

; initialize push-button debounce circuit
sbi DDRD,dff_clk // flip-flop clock, DDRD5 = 1; PORTD5 = Undefined
cbi PORTD,dff_clk // DDRD5 = 1; PORTD5 = 0
cbi DDRD,dff_Q // flip-flop Q DDRD2 = 0; PORTD2 = Undefined
cbi PORTD,dff_Q // flip-flop Q DDRD2 = 0; PORTD2 = 0

REGISTER SUMMARY AND THE I/O PORT

  • Three I/O memory address locations are allocated for each port, one each for the Data Register – PORTx, Data Direction Register – DDRx, and the Port Input Pins – PINx.
  • The Port Input Pins I/O location PINx is Read Only, while the Data Register and the Data Direction Register are read/write.
  • However, Writing a logic one to a bit in the PINx Register, will result in a Toggle in the corresponding bit in the Data Register.
  • In addition, the Pull-up Disable – PUD bit in MCUCR disables the pull-up function for all pins in all ports when set.

Figure 10: Port B & D Data Register Summary

I/O PORT PIN SCHEMATIC

Figure 11: General Digital I/O

I/O PORT PIN CONFIGURATIONS

Inputs Outputs
DDRXn PORTXn I/O Pull-Up Comments
0 0 Input No Read “Synchronized” PINXn
0 1 Input Yes
1 X Output N/A Write bit to PORTXn

Appendix

APPENDIX A – PROGRAM I/O PORT AS AN INPUT USING MNEMONICS

GPIO Port as an Input

.INCLUDE
; C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m328Pdef.inc

in r16,DDRC // DDRC equated to 0x07 in m328Pdef.inc
cbr r16,(1<<pc5)|(1<<pc4)|(1<<pc3)|(1<<pc2)|(1<<pc1)|(1<<pc0)< span=””> out DDRC,r16 // output DDxn = 0; PORTxn = Undefined
in r16,PORTC // PortC equated to 0x08
sbr r16,(1<<pc5)|(1<<pc4)|(1<<pc3)|(1<<pc2)|(1<<pc1)|(1<<pc0)< span=””> out PORTC,r16 // output DDxn = 0; PORTxn = 1</pc5)|(1<<pc4)|(1<<pc3)|(1<<pc2)|(1<<pc1)|(1<<pc0)<></pc5)|(1<<pc4)|(1<<pc3)|(1<<pc2)|(1<<pc1)|(1<<pc0)<>

.INCLUDE “spi.inc”
The following Define and Equate Assembly Directives are defined in spi_shield.inc
.DEF spi7SEG=r8 // Text Substitution (copy-paste)
.DEF switch=r7
.EQU seg_a=0 // Numeric Substitution

in switch, PINC // R7 <- PINC
bst switch,4 // T <- R7 bit 4
bld spi7SEG,seg_a // R8 bit 0 <- T

Appendix B – I/O PORT PIN “SYNCHRONIZER”

  • As previously discussed, you read a port pin by reading the corresponding PINxn Register bit. The PINxn Register bit and the preceding latch constitute a synchronizer. This is needed to avoid metastability if the physical pin changes value near the edge of the internal clock, but it also introduces a delay as shown in the timing diagram.
  • Consider the clock period starting shortly after the first falling edge of the system clock. The latch is closed when the clock is low, and goes transparent when the clock is high, as indicated by the shaded region of the “SYNC LATCH” signal. The signal value is latched when the system clock goes low. It is clocked into the PINxn Register at the succeeding positive clock edge. As indicated by the two arrows tpd,max and tpd,min, a single signal transition on the pin will be delayed between ½ and 1½ system clock period depending upon the time of assertion.

I/O Port Pin Synchronizer with Timeline

Appendix C – SWITCHING BETWEEN I/O PORT PIN CONFIGURATIONS

  • When switching between tri-state ({DDxn, PORTxn} = 0b00) and output high ({DDxn, PORTxn} = 0b11), an intermediate state with either pull-up enabled ({DDxn, PORTxn} = 0b01) or output low ({DDxn, PORTxn} = 0b10) must occur.
  • Switching between input with pull-up ({DDxn, PORTxn} = 0b01) and output low ({DDxn, PORTxn} = 0b10) generates the same problem. You must use either the tri-state ({DDxn, PORTxn} = 0b00) or the output high state ({DDxn, PORTxn} = 0b11) as an intermediate step.