El Registro PORT (Puerto) en Arduino

2
6502
Arduino Mega el cual posee varios puertos.

En este post veremos qué son los PORT y cómo se utilizan. Al final lograremos manipular en bajo nivel y de manera más rápida los contactos de entrada/salida del microcontrolador de las placas Arduino.

Los pines usados en la placa Arduino (el ATmega8 y el ATmega168) poseen tres puertos (El ATmega328 (Arduino Uno) usa la misma configuración de pines que el ATmega168):

  • B (pines digitales del 8 al 13)
  • C (entradas analógicas)
  • D (pines digitales del 0 al 7)
Puertos que posee el Arduino ATmega328
Puertos que posee el Arduino ATmega328

Para más detalles sobre cómo están mapeados los números de los pines de Arduino a los puertos y los bits observa la siguiente imagen:

Números de los pines de Arduino a los puertos y los bits.
Números de los pines de Arduino a los puertos y los bits.

El Arduino Mega presenta varios puertos B,C,D,E,F, etc.

Cada puerto es controlado por tres registros, los cuales también están definidos como variables en el lenguaje del Arduino.

  • El registro DDR, determina si el pin es una entrada o una salida.
  • El registro PORT controla si el pin está en nivel alto o en nivel bajo.
  • El registro PIN permite leer el estado de un pin que se ha configurado con entrada usando la función pinMode().

“Los registros DDR y PORT pueden ser ambos, escritos y leídos. El registro PIN corresponde al estado de las entradas así que solo puede ser leído.” El PORTD mapea los pines digitales del 0 al 7

  • DDRD – El registro de configuración del modo de los pines del puerto D – lectura/escritura
  • PORTD – Registro de datos del puerto D – lectura/escritura
  • PIND – Registro de pines de entrada – solo lectura

El PORTB mapea los pines digitales del 8 al 13. Se debe recordar que… Los bits altos (6 & 7) están mapeados a los pines del cristal de cuarzo y no pueden ser usados. Estos son solamente accesibles en el Arduino Mini.

  • DDRB – El registro de configuración del modo de los pines del puerto B – lectura/escritura
  • PORTB – Registro de datos del puerto D – lectura/escritura
  • PINB – Registro de pines de entrada – solo lectura

El PORTC mapea los pines de entrada analógica del 0 al 5.

  • DDRC – El registro de configuración del modo de los pines del puerto B – lectura/escritura
  • PORTC – Registro de datos del puerto D – lectura/escritura
  • PINC – Registro de pines de entrada – solo lectura

Cada bit de estos registros corresponden con un solo pin; por ejemplo el bit menos significativo de los registros DDRB, PORTB, y PINB hace referencia al pin PB0 (pin digital 8)

Normalmente antes para declarar un pin lo hacíamos de la siguiente manera:

Entonces si quisiéramos declarar 7 pines (desde el digital 0 al digital 7), tendríamos que repetir pinMode 7 veces. Al igual que escribir tendríamos que poner digitalWrite(pin,estado) pin 0 estado alto, pin 1 estado bajo, etc.

Al utilizar Registros PORT (Puerto) tenemos la ventaja de que con solo una instrucción podemos declarar el pin como entrada o salida y también podemos escribir, si lo queremos, como estado HIGH o LOW.

Para controlar cualquiera de los tres puertos, debemos usar dos instrucciones.

  • Primera instrucción: se debe declarar en la estructura void setup() y nos sirve para declarar si el pin se va a usar como INPUT o como OUTPUT.

Dato Importante:

“Los pines 0 y 1  son la transmisión serial (RX y TX respectivamente). Si utilizas “Serial.begin” en alguno de esos 2 puertos; no tendrás comunicación serial. Cuidado con eso.”

Ejemplo:

1 = OUTPUT                                  0 = INPUT

DDRX = B11111110;

donde X es la letra del puerto a usar (BCD). Sin embargo si queremos tener comunicación Serial tendríamos que hacer esto:

DDRX = DDRX | B11111100;

Esta manera es más segura ya que configura los pines del 2 al 7 como salidas sin cambiar los pines 0 y 1, que como mencionamos son RX y TX Para tener más referencia de los operadores bit a bit tipo AND, visita el siguiente post de Arduino:

Tenemos el siguiente código:

B11111110;

Colocamos B, porque el número a marcar es Binario. Para ampliar más sobre los tipos de datos en Arduino visitemos el siguiente blog:

Para saber el estado que le daremos al pin siempre lo pondremos escribiendo de derecha a izquierda.

Número a marcar

1

1

1

1

1

1

1

0

Ubicación del pin en Arduino.

7

6

5

4

3

2

1

0

  • Segunda instrucción: es la escritura del puerto (esta variará en función del programa que estemos desarrollando). Lo localizamos en la función void loop().

Ejemplo:

1 =HIGH                   0 = LOW

PORTX= B11111110;

En este ejemplo los pines del 1 al 7 permanecerán encendidos (HIGH) y el pin 0 LOW. Veamos un ejemplo aplicando estos conceptos:

En este ejemplo lograremos que durante dos segundos todos los leds enciendan, durante dos segundos más alumbren los impares y durante dos más todos se apaguen. Veamos:

Configuración Utilizada:

Registro PORT
Configuración Utilizada para este proyecto.

Abrimos Arduino IDE y escribimos el siguiente código:

 Para ver otro ejemplo utilizando Registro PORT (Puerto), visitemos el siguiente post:

Ventajas y Desventajas que nos ofrece al utilizar el Registro PORT (Puerto):

Desventajas:

  • El código es mucho más difícil de depurar y mantener, y es mucho más difícil de entender para la gente. Solo lleva algunos microsegundos al procesador ejecutar código, pero podría llevarte horas descubrir por qué no funciona y arreglarlo.
  • Es mucho más fácil causar mal funcionamiento no intencionado usando el acceso directo a un puerto. Observa como la línea DDRD = B11111110, de arriba, menciona que el pin 0 se debe dejar como una entrada. El pin 0 la línea de recepción (RX) en el puerto serial.Podría ser muy fácil causar que tu puerto serial deje de funcionar por cambiar el pin 0 a una salida.

Ventajas:

  • Puede que puedas cambiar los pines de estado muy rápido, en fracciones de microsegundos. Las funciones digitalRead() y digitalWrite() son cada una cerca de una docena de líneas de código, lo cual al ser compilado se convierte en unas cuantas instrucciones máquina.

Cada instrucción maquina necesita un ciclo de reloj a 16MHz, lo cual puede sumar mucho tiempo en aplicaciones muy dependientes del tiempo. El Registro PORT (Puerto) puede hacer el mismo trabajo en muchos menos ciclos de trabajo.

  • Algunas veces necesitamos configurar muchos pines exactamente al mismo tiempo. Por lo que usar las funciones digitalWrite (10,HIGH), seguida de la función digitalWrite (11,HIGH), causará que el pin 10 se ponga en nivel alto varios microsegundos después que el pin 11, lo cual puede confundir circuitos digitales conectados al Arduino, cuyo funcionamiento dependa del tiempo preciso del cambio de esos bits.
  • Si te estás quedando sin memoria para tu aplicación, puedes usar estos trucos para hacer que tu código sea más pequeño. Usando este método se necesitan muchos menos bytes de código compilado que si se hace un bucle para que se vaya cambiando cada pin uno por uno.

Espero que la información suministrada sea de su comprensión y utilidad. Recuerda seguir visitando nuestros post.

Saludos.

Compartir
José José Villalaz Díaz, nació el 6 de junio de 1994 en la ciudad de Chitré, provincia de Herrera. Con residencia en La Villa de Los Santos, recibió sus estudios primarios en la Escuela Nicanor Villalaz. Luego realiza sus estudios secundarios en el Instituto Coronel Segundo de Villarreal en donde siguiendo su entusiasmo por aprender y enseñar, a través de dedicación y esfuerzo, recibió la medalla de honor al mérito de primer puesto. Con ganas de mejorar el negocio familiar dedicado a la mecánica y siguiendo un poco los pasos de sus padres y hermanos, decide ingresar a la Universidad Tecnológica de Panamá en donde descubre gran interés por el área de eléctrica. Actualmente estudia Licenciatura en Ingeniería Electromecánica. Hoy día es un estudiante universitario comprometido con sus estudios, con la excelencia, con compartir nuevos conocimientos y ser mejor persona cada día. Aspira convertirse en un buen profesional para colaborar con su país en cuanto a tecnología, tener siempre la disposición de servir a las demás personas y llevar a todos los usuarios que ingresan a este sitio contenidos de calidad.
  • Aprendiz de Ingeniero

    Disculpa, tengo una duda a la hora de leer todo un puerto. En mi caso necesito leer 4 valores a la vez (valores digitales), pero a la hora de utilizar el digitalread sólo lee las primeras 2 entradas, ignorando las otras 2. Cómo tu mencionas, a la hora de utilizar el comando “port” se conoce todo el estado del puerto. ¿De qué forma haría para leer el valor de esas 4 entradas en una sola instrucción? De antemano gracias 😀

    • Si estas utilizando un solo puertao para leer las cuatro entradas, no creo que haya problema a la hora de leerlo con digitalRead(). Ahora, si quieres leer el valor de este registro, debes almacenarlo en una variable. Por ejemplo: byte readPortD = PIND;. Ahora, dependiendo de cuál bit dentro del puerto hayas declarado como salida, así mismo deberás enfocarte en únicamente esos valores dentro del puerto.