Escribir en los pines en un puerto sin afectar a otros pines en ese puerto

5

Estoy emitiendo un número de 6 bits en PORTA (RA0-RA5), ¿cómo escribo en esos bits sin desordenar lo que ya está en RA6 y RA7?

Por ejemplo, si quiero generar 0x3F en los bits RA0-RA5. Si utilizo PORTA = 0x3F; , la salida 00111111 se borrará de manera efectiva de lo que ya se haya escrito en los bits RA6 y RA7.

Estoy codificando en C con MikroC en un PIC18

    
pregunta Gozmit

3 respuestas

8

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.

    
respondido por el Tom Carpenter
8

Generalmente, en la arquitectura PIC18, nunca debe usar comandos de lectura-modificación-escritura como

PORTA | = 0x3F; // establece los bits 0 a 5

En su lugar, utilice

LATA | = 0x3F; // establece los bits 0 a 5

o

LATA & = ~ 0x80; // borrar el bit 7

El motivo es que la instrucción PORTA | = xx lee primero los niveles de bits en los pines, los modifica y luego escribe el resultado en el cierre del puerto.

La instrucción LATA lee los bits en el cierre de puerto, los modifica y luego escribe el resultado en el cierre de puerto.

Si, por algún motivo (como demoras de carga o propagación), los pines del puerto no están en los niveles lógicos correctos y válidos, la instrucción de lectura-modificación-escritura puede modificar inadvertidamente los bits que no pretendía modificar. Si está cambiando los pines de entrada a salida para simular pines de drenaje abiertos, surge un problema similar para los pines que son entradas temporales: el pestillo de salida de un pin diferente al que está modificando intencionalmente los cambios, y luego cuando cambia el registro TRIS a 0 para activar el drenaje abierto simulado, el estado de bloqueo de ese bit se ha alterado.

Para los PIC más antiguos que no tienen LATx, si tiene que usar RMW, puede mantener un registro sombra manualmente, modificarlo y luego transferir el resultado al registro de puerto.

Un poco más de detalles sobre lo que escribí anteriormente, de su proveedor del compilador aquí .

    
respondido por el Spehro Pefhany
1

Para manipular solo el bit menos significativo (LSB) de un registro

Configurar

GPIO_DATA = GPIO_DATA | 0x01;

Clear

GPIO_DATA = GPIO_DATA & (~0x01);

A continuación hay un conjunto de notas que tengo a mano que podrían ser útiles. Presta atención a las notas en rojo.

Paraobtenerunaexplicacióndetallada,lesugieroqueconsulte aquí .

Referencias:

respondido por el Mahendra Gunawardena

Lea otras preguntas en las etiquetas