Para quien no lo sepa, y por ser el primer post sobre Arduino en el blog, Arduino es una plataforma de electrónica abierta para la creación de prototipos basada en software y hardware flexibles y fáciles de usar. Se creó para artistas, diseñadores, aficionados y cualquiera interesado en crear entornos u objetos interactivos [1]. Es decir, “hardware libre”, por utilizar una similitud con el “software libre”.
Hay mucha información en Internet de cómo aprender a manejar el dispositivo, con muchos ejemplos explicados casi paso a paso, además de video-tutoriales. Sin embargo, no todo está fácilmente accesible, o simplemente no está puesto de una forma suficientemente clara para alguien que está iniciándose, como por ejemplo, cómo se hace para enviar más de un bit a la vez a los puertos de salida digital, que es de lo que me ocuparé en esta entrada.
Para averiguarlo, tuve que mirar el esquemático de mi antiguo Duemilanove™ [2] y las palabras reservadas del lenguaje [3, 4]. El resultado es que, efectivamente, se pueden manejar los puertos directamente, y la forma, para manejar como salida la expondré aquí:
0.- ¿Qué puertos podemos utilizar?
Para los ATmega8 y los ATmega168, tenemos los siguientes puertos:
- B: pertenece a los pines digitales 8 a 13. Como tiene realmente 6 pines, los dos bits más significativos no se usan.
- C: pertenece a los pines de las entradas analógicas. En éste post no lo trataré.
- D: pertenece a los pines digitales 0 a 7.
1.- Configurar los pines digitales deseados como entrada/salida.
Para ello podemos hacerlo de uno a uno con la tradicional instrucción pinMode(pin, OUTPUT) con cada uno de ellos o modificar el registro DDR asociado al puerto completo. En el siguiente ejemplo se muestra cómo hacerlo usando el puerto D:
1 2 3 4 |
DDRD = B11110000; // Pines de 0 a 3 como entradas // y 4 a 7 como salídas digitales. DDRD = 0xF0; // En hexadecimal. DDRD = 240; // En base decimal. |
Sin embargo, también hay una forma de cambiar la configuración del puerto de forma segura, cuando vas a usar un subconjunto, sin afectar al resto de pines: Usando máscaras y operaciones lógicas, la operación OR para modificar como salida digital, y la AND para modificar como entrada digital, de la siguiente manera:
1 2 3 4 5 6 7 8 9 10 |
DDRD = DDRD | 0xF0; // Pone los pines 4 a 7 como salida // digital y NO modifica la configuración // que tuviesen los pines 0 a 3. DDRD = DDRD & 0xF0; // Pone los pines 0 a 3 como entrada // digital y NO modifica la configuración // que tuviesen los pines 4 a 7. // También se puede poner de forma acortada de la // siguiente manera: DDRD |= 0xF0; DDRD &= 0xF0; |
Si tenéis dudas en el uso de los operadores a nivel de bit, podéis consultar [5].
2.- Lectura y escritura usando los puertos directamente.
Tanto la lectura como la escritura de un puerto digital se hace de forma análoga al registro DDR, y al igual que con ese registro, recomiendo el uso de máscaras. Obviamente se puede usar tanto binario, decimal como hexadecimal en las operaciones, aunque para el ejemplo esté usando únicamente hexadecimal.
1 2 3 4 |
DDRD = 0xF0 // Pines 0 a 3 como entradas y // 4 a 7 como salidas. PORTD |= 0x80 & 0xF0 ; //Escritura var = PORTD & 0x0F; // Lectura |
Las máscaras en el caso anterior son 0xF0 y 0x0F.
También cabe recordar que el negador a nivel de bit en Arduino es “~”, y que, en nuestro caso de ejemplo, podríamos usar de la siguiente manera obteniendo idéntico resultado:
1 2 3 4 5 |
int MASK = 0xF0; DDR = MASK; PORTD |= 0X80 & MASK; var = PORTD & ~MASK; |
Bibliografía
[1] http://arduino.cc/en/
[2] http://arduino.cc/en/uploads/Main/arduino-duemilanove-schematic.pdf
[3] http://www.arduino.cc/en/Reference/PortManipulation
[4] http://chip-yang.myweb.hinet.net/Keywords.html
[5] http://playground.arduino.cc/Code/BitMath
Deja un comentario