Un procedimiento llamado "Lectura-Modificar-Escritura".
Lo que implica está completamente en el nombre. Tú lees. Entonces te modificas. Luego escribes.
Leer:
//Read in the value of the output register
tempVariable = [output register]
Modificar:
//set all bits you want to modify to be 0.
tempVariable &= [some mask];
//or in the values of the bits with those bits you want unchanged set to 0
tempVariable |= [new value of bits];
Escribe:
//Write the new value back to the output register
[output register] = tempVariable;
La clave es básicamente terminar con los valores de los bits que desea que no se modifiquen para volver a escribirlos en el registro de salida junto con los nuevos valores de los bits que desea cambiar.
Para determinar cuál es el registro de salida para su dispositivo, debe consultar su hoja de datos.
No podemos simplemente escribir en el registro directamente porque afectará los bits que no queremos cambiar también. Por lo tanto, necesitamos una secuencia de operaciones que cambiará solo los bits que queremos. Aquí es donde entran los operadores bitwise.
Hay varios operadores bitwise, pero los dos importantes son &
(and) y |
(o). Bitwise y cualquier cosa con un 0 y establece que ese bit sea 0, bitwise y cualquier cosa con 1 y permanece igual. Bitwise o cualquier cosa con un 1 y establece que bit sea un 1, bitwise o cualquier cosa con 0 y permanece igual. Estos dos operadores nos permiten realizar los cambios necesarios porque ahora tenemos una manera de establecer solo algunos bits en 0 y una forma de establecer solo algunos bits en 1.
El nuevo valor que desea escribir requerirá que algunos bits se ajusten a 0 y algunos bits a 1. Podemos lograr esto haciendo y a nivel de bits seguidos de o . y se usan para configurar todos los bits que queremos cambiar a 0 para que luego podamos hacer o , que establece que solo los bits que queremos que sean 1 sea 1 .
Un ejemplo ayudará. Digamos que desea modificar los 5 bits más bajos a un valor de 0b01011
pero dejar los 3 bits superiores sin cambios. Digamos también que el valor actual es 0b10111101
. Así que seguimos el procedimiento:
Paso 1, máscara:
Current: 0b101 11101
Bitmask: 0b111 00000 <- remember a 1 means don't change, a 0 means clear.
Result : 0b101 00000
Paso 2, modificar:
Masked : 0b101 00000
New Val: 0b000 01011 <- remember a 1 means set to 1, a 0 means unchanged
Result : 0b101 01011
Y ya está: observe que los 3 bits superiores no se modificaron en ambas operaciones, mientras que los bits inferiores se actualizaron para coincidir con el nuevo valor.
Para resaltar un punto mencionado en los comentarios y la otra respuesta, que esto debe hacerse en el registro de salida, que fue la intención original de mi respuesta. Parece que hay cierta confusión al suponer que por puerto me refería a los registros PORTx en los PIC, de hecho, el registro de salida en algunos dispositivos es el registro LATx. Algunos PIC no tienen un registro LATx. En AVRs, por ejemplo, PORTx es el registro de salida. La hoja de datos de su dispositivo le indicará qué es el registro de salida.
Además, la técnica se puede usar para modificar variables y registros, y se puede usar cuando se modifican los registros para otras cosas que no sean solo puertos de E / S; puede modificar elementos como los registros de control para periféricos en serie y también .
Debido a las diferencias en la denominación de los registros y al hecho de que el proceso es un enfoque muy universal, en el ejemplo anterior intenté ser genérico, ya que lo mismo se aplica no solo a los PIC, sino a cualquier microcontrolador, de hecho casi todo. eso requiere que algunos bits de un registro sean modificados pero otros no.