Operador PIC Assembler Bit Wise | Inclusivo o

1

Estoy siguiendo un tutorial sobre la programación de PIC serie 12F en ensamblador.

Tengo una pregunta relacionada con los operadores bitwise específicamente el < < operador de desplazamiento a la izquierda cuando se combina con el | operador incluido O.

Por ejemplo, digamos que estoy usando un PIC 12F508 y quiero configurar los bits para usar el temporizador 0, asignar el preescalador al temporizador 0 y usar una escala 1: 256 en el registro de opciones.

También quiero que los otros bits que no estoy tocando se mantengan en 1 ya que el registro de opción por defecto es 11111111.

En lugar de especificar los bits directamente, como

movlw    b'11010111'
option

Prefiero tratar los bits por nombre como se especifica en el archivo de inclusión PIC12F508 de esa manera, es menos probable que borre el bit incorrecto.

Me gusta esto:

movlw    1<<NOT_GPWU | 1<<NOT_GPPU | 0<<T0CS | 1<<TOSE | 0<<PSA | b'111'
option    

Prefiero no abordar los bits de conjunto de prescaler individuales por nombre, ya que creo que hace que sea más difícil de leer.

Esto se introdujo en el tutorial y creo que entiendo cómo funciona esto, pero solo quiero verificar que entiendo lo que está pasando.

Primero, el orden de precedencia para los operadores a nivel de bits es el siguiente:

~  compliment

left shift  <<

right shift >>

bitwise AND &

bitwise exclusive OR ^

bitwise inclusive OR |

En otras palabras, si no hay () paréntesis que cambie el orden de precedencia, los operadores hacia la parte superior de la lista se realizarán primero.

Por lo tanto, desde < < izquierda desplazarla en la parte superior de la lista y el inclusivo o | está en la parte inferior. Los desplazamientos a la izquierda se realizan primero.

Por ejemplo, NOT_GPPU = 1 < < 6 ya que 6 se especifica como la posición del bit en el archivo de inclusión. Entonces 01000000 sería el resultado.

T0CS = 0 < < 5 ya que 5 se especifica como la posición de bit en el archivo de inclusión. Entonces 00000000 sería el resultado. Este desplazamiento a la izquierda no es necesario, ya que no hace nada cuando 0 a la izquierda desplazada 5 veces sigue siendo 0, pero especifica en qué se establece el bit T0CS para mayor claridad.

Así que al bajar de la línea de MSB a LSB después de los turnos a la izquierda, tenemos:

GPWU 10000000

GPPU 01000000

T0CS 00000000

TOSE 00010000

PSA > 00000000

-------------- 111

Por lo tanto, ahora estos valores u ORed incluidos juntos por el ensamblador para obtener el valor final que se moverá al registro de opción.

------- 11010111 = Resultado de OR inclusivo

Bitwise inclusiva o tabla de verdad:

A   B   Out
1   1   1
0   0   0
1   0   1
0   1   1

Entonces, entonces:

movlw    1<<NOT_GPWU | 1<<NOT_GPPU | 0<<T0CS | 1<<TOSE | 0<<PSA | b'111'
option

Se convierte en:

movlw    b'11010111'
option

Entonces, según mi entendimiento, ni siquiera tengo que poner los turnos de la izquierda en el orden de bits correcto, ¿no?

Por ejemplo:

movlw    0<<T0CS | 1<<NOT_GPPU | 1<<NOT_GPWU | 0<<PSA | 1<<TOSE | b'111'
option

Por supuesto, tiene más sentido ponerlos en orden, pero obviamente los últimos 3 bits son sensibles a la posición porque no los estoy especificando por nombre (PS2, PS1, PS0).

¿Pero debería producirse la misma salida binaria 11010111?

Gracias de antemano.

    
pregunta Krankshaft

2 respuestas

4

Sí, parece entender correctamente cómo MPASM procesa las expresiones numéricas.

Si bien el uso de los nombres de bits es mucho mejor que los valores HEX codificados de manera rígida que la mayoría de la gente usa, creo que hay una manera mejor. El problema con los nombres de los bits es que pueden ser crípticos, y usted confía en el nombre solo para explicar lo que hace cada bit. Este método tampoco funciona bien con campos de múltiples bits, como lo demuestra con b'111 'al final. Tuve que buscar en la hoja de datos para encontrar que estos son los bits de selección del divisor del prescaler.

Me gusta mostrar cada campo en una línea separada para que cada uno tenga su propio comentario de final de línea. Este es un ejemplo de cómo configurar el registro OPCIONAL en algún código 12F508 de 2009:

         movlw   b'01000010' ;set OPTION register
                 ; 0-------  wake-up on change enabled
                 ; -1------  weak pullups disabled on GP0,GP1,GP3
                 ; --0-----  timer 0 clocked from instruction clock
                 ; ---0----  timer 0 inc on rising edge of T0CKI (not used)
                 ; ----0---  prescaler assigned to timer 0
                 ; -----010  prescaler = 1:8
         option

Utilizo este método para la mayoría de las configuraciones de SFR.

    
respondido por el Olin Lathrop
3

Sí, no importa en qué orden los ponga, y de hecho, la idea de usar los nombres es que no necesita saber qué números representan en el momento en que los usó. Si solo pudiera usarlos en un orden particular, entonces los nombres representarían un riesgo enorme.

Comúnmente, uno no incluiría todos los bits que NO están establecidos, así que en lugar de

1<<NOT_GPWU | 1<<NOT_GPPU | 0<<T0CS | 1<<TOSE | 0<<PSA | b'111'

uno podría escribir

1<<NOT_GPWU | 1<<NOT_GPPU | 1<<TOSE | b'111'

Siempre debe asegurarse de tener claro si la persona que escribió los encabezados está utilizando números de bits o proporcionando la máscara completa (es decir, el cambio ya se ha realizado): es común y usted necesita saber cuál Es que cuando llegas a utilizarlos.

    
respondido por el user1844

Lea otras preguntas en las etiquetas