Puertos

Objetivos

  • Comprender el funcionamiento de los puertos en el microcontrolador AVR
  • Aprender a configurar los puertos adecuadamente

Introducción

Todos los puertos AVR tienen verdadera funcionalidad de lectura-modificación-escritura cuando se utiliza como E/S digitales. Esto significa que la dirección de uno de los pines se puede cambiar sin cambiar la dirección de cualquier otro con las instrucciones del SBI y la CBI. Lo mismo se aplica cuando se cambia el valor (si está configurado como salida) o la activación/desactivación de las resistencias pull-up (si está configurado como entrada). El controlador de cada pin es lo suficientemente robusto como para alimentar directamente indicadores LED. Todos los pines del puerto tienen resistencias pull-up seleccionables individualmente con una resistencia invariante del suministro de voltaje. Todos los pines I / O tienen diodos de protección tanto a VCC y tierra como se indica en la figura.

ports1.png

Funcionamiento

Cada pin del puerto consiste en tres registros de bits: DDxn, PORTxn y PINxn, se configuran en los registros DDRx, PORTx y PINx respectivamente (reemplazar la x por el nombre del puerto).

El bit DDxn en el Registro DDRx selecciona la dirección de este pin. Si en DDxn se escribe un uno lógico, Pxn está configurado como un pin de salida. Si DDxn está escrito como cero lógico, Pxn está configurado como un pin de entrada.

Si en PORTxn se escribe un uno lógico cuando el pin está configurado como entrada, se activa la resistencia de pull-up. Para desactivar la resistencia de pull-up, el puerto tiene que ser escrito en cero lógico o el pin tiene que estar configurado como salida. Los pines del puerto son tri-estado cuando una condición de reposición se activa, incluso si no hay relojes en ejecución.

Si en PORTxn se escribe uno lógico cuando el pin está configurado como un pin de salida, el pin del puerto es conducido en estado alto (uno). Si en el puerto es escrito un cero lógico cuando el pin está configurado como un pin de salida, el pin del puerto es conducido en estado bajo (cero).

Al cambiar entre los tres estados ({DDxn, PORTxn} = 0b00) y la salida en alto ({DDx, PORTxn} = 0b11), un estado intermedio, ya sea con pull-up activado ({DDxn, PORTxn} = 0B01) o la salida baja ( {DDxn, PORTxn} = 0b10) debe ocurrir. Normalmente, el estado de pull-up habilitado es totalmente aceptable, como un ambiente de alta impedancia. Si este no es el caso, el bit PUD en el Registro SFIOR se puede configurar para desactivar todas las resistencias de pull-up en todos los puertos.

Independiente de la configuracion del registro DDxn es posible leer el valor del puerto PINxn.

ports2.png

En la siguiente figura se muestra el diagrama de los registros que controlan el puerto A:

ports3.png

A manera de ejemplo ilustremos una situación en donde se desea leer los datos del puerto A del microcontrolador y luego escribirlos en el Puerto B.

Para esto entonces es necesario configurar los puertos adecuadamente:

Para el puerto A se ajustará el DDRA (Data direction register PORTA) con todos los bits en cero para que el puerto A sea entrada.

ldi r16,0x00            ; se carga el registro 16 con cero
out DDRA,r16            ; se habilita el puerto A como entrada

A continuación se configurarán los 8 bits del puerto B como salida, para esto se utilizará el registro DDRB (Data direction register PORTB) con todos los bits en uno.

ldi r16,0xFF            ; se carga el registro 16 con unos 
out DDRB,r16            ; se habilita el puerto A como entrada

Para leer los datos del puerto A se utilizará el registro PINA (Port IN - A)

in r16, PINA            ; lectura del puerto A

Al utilizar la instrucción in se hace uso de uno de los registros de propósito general.

Para escribir datos en el puerto B se utilizará el registro PORTB.

out PORTB,r16           ; enviar el contenido de r16 al puerto B

Es importante tener en cuenta que el registro PORTx tambien sirve para habilitar las resistencias de pull-up en caso que este se halla configrado como entrada.


Código Ejemplo.

En el siguiente código se configuran los puertos A y B como entradas y salidas respectivamente se realiza una lectura en el puerto A y el dato leido se escribe en el puerto B

.org 0                    ;posicion del vector de interrupción RESET
rjmp reset
 
reset:
    ldi r16,high(RAMEND)
    out SPH,r16
    ldi r16,low(RAMEND)
    out SPL,r16             ; se carga la pila del microcontrolador
    ldi r16,0x00            ; se carga el registro 16 con cero
    out DDRA,r16            ; se habilita el puerto A como entrada
    ldi r16,0xFF            ; se carga el registro 16 con unos
    out DDRB,r16            ; se habilita el puerto B como salida
secuencia:
    in r16, PINA            ; lectura del puerto A
    nop                
    nop                     ; tiempo para establecerse
    out PORTB,r16           ; enviar dato al puerto B
    rjmp secuencia

Referencias

[1] Hoja de datos del microcontrolador ATMEGA16

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License