El lenguaje de programación C cuenta
con una operación especial para tratar con bits, la cual se representa por dos
signos “menor que” seguidos <<
o dos signos de “mayor que” seguidos >>.
Éstas son operaciones de desplazamiento
de bits.
El valor a la izquierda del signo << o >> es desplazado un cantidad de veces definida por el valor a
la derecha del mismo signo. Si se usa <<,
entonces los bits son desplazados hacia la izquierda, y si se usa el signo >> los bits son desplazados hacia
la derecha, por ejemplo:
Notar como se agregan ceros 0 a la derecha en el número, y los número desplazados, que estaban a la izquierda, desaparecen. Esto sucede porque las operaciones se realizaron en registros, o valores, de 8 bits. Si se trabaja con registros de 16 bits, pasaría esto:
Notar como se agregan ceros 0 a la derecha en el número, y los número desplazados, que estaban a la izquierda, desaparecen. Esto sucede porque las operaciones se realizaron en registros, o valores, de 8 bits. Si se trabaja con registros de 16 bits, pasaría esto:
Veamos
algunos ejemplos de aplicación para manipulación de puertos (aunque no se usa únicamente para puertos, sino para registros en general):
Si quieres activar el bit más bajo (el
bit de más bajo valor posicional, o bit 0) del puerto A (PORTA), puedes escribir el valor 1 a PORTA, ya que 1 en binario es 0b00000001, de esta forma:
PORTA = 1;
Si quieres activar el bit 1 (segundo
bit, recordemos que están numerados del 0 al 7), se logra mediante:
PORTA = 2;
Ya que 2 decimal es 0b00000010.
Sin embargo es más sencillo así:
PORTA = (0x01<<1);
En la línea anterior, el valor 0x01 (0b00000001) será desplazado a la izquierda una vez, por lo que se convertirá en 0x02, que en binario es 0b00000010,
con lo cual se activa el bit 1 del puerto
A. En lugar de usar 0x01 se pudo
usar 1.
De igual forma, si quieres activar el
bit más alto del puerto A, lo hacemos con:
PORTA = (1<<7);
También se podría lograr con:
PORTA = 128;
Ya que 128 decimal es igual a 0b10000000.
¿Cómo activar varios bits al mismo tiempo?
En ocasiones, queremos activar varios
bits al mismo tiempo, ¿cómo hacemos esto sin tener que calcular el valor
decimal que corresponda a esto?
Por ejemplo, para activar los bits 6 y 1, tendríamos que calcular que se necesita el valor decimal 66, ya que 66 es igual a 0b01000010,
con lo que se activarían los bits 1 y 6.
En lugar de realizar este cálculo,
podemos activar ambos bits de manera simultánea usando la operación lógica or, que se realiza con el operador |
en C.
PORTA = (1<<1) | (1<<6);
Precompilador
Estos desplazamientos de bits se
computan en el precompilador, antes de que el código llegue al compilador, por
lo que no toman ningún tiempo extra durante el tiempo de ejecución.
Macro _BV
Los programadores que escribieron WinAVR decidieron que la manipulación
de bits es tan común que desarrollaron una macro para esto.#DEFINE _BV(bit) (1<<bit)
Esta
macro está predefinida en WinAVR así que no tienes que definirla tú, la puedes
usar cuando quieras. Usándola, la
operación anterior quedaría como:
PORTA = _BV(1) | _BV(6);
Esta macro no existe en otras versiones de C. Si la quieres usar, sólo necesitas copiar y pegar este texto #DEFINE _BV(bit) (1<<bit) en la parte superior de tu código y ya estás listo para usarla.
Activar un bit del Puerto sin modificar
los demás bits
En ocasiones, queremos modificar
únicamente el valor de un bit del puerto pero SIN MODIFICAR LOS VALORES DE LOS OTROS BITS, por ejemplo, si queremos
activar el bit 3, sin modificar el resto de los bits, se logra mediante:PORTA = PORTA | _BV(3);
Esto se puede simplificar gracias a
que C permite lo siguiente:
PORTA |= _BV(3);
El comando |= cumple dos funciones al mismo tiempo, realiza la operación lógica OR y asigna el resultado de la operación en un solo paso. De esta forma valor |= 1; es lo mismo que valor = valor | 1;