Pregunta

Me estoy confundiendo al cambiar de banco en el ensamblador PIC ... Esto funciona para poner una 'Q' en el usart:

bsf PORTB,1         ;Set Transmit DIR (PORTB (0x6) not mirrored in other banks)
movlw 'Q'           ;'Q' to work reg
movwf TXREG         ;work reg to TXREG (TXREG (0x19) not mirrored in other banks)
clrwdt              ;Clear watchdog
btfss TXSTA,TRMT    ;Wait until 'Q' is shifted (TXSTA is 0x18, not mirrored)
goto $-2
bcf PORTB,1         ;Set Recive DIR

Y esto funciona igual de bien:

BCF 0x3, 0x5        ;Switch to bank 0
BCF 0x3, 0x6
bsf PORTB,1         ;Set Transmit DIR
movlw 'Q'           ;'Q' to work reg
movwf TXREG         ;work reg to TXREG 
BSF 0x3, 0x5        ;Switch to bank 1
clrwdt              ;Clear watchdog
btfss TXSTA,TRMT    ;Wait until 'Q' is shifted
goto $-2
BCF 0x3, 0x5        ;Switch to bank 0
bcf PORTB,1         ;Set Recive DIR

He comprobado que el compilador no realiza ningún cambio de banco cuando no estoy viendo ... ¿Cuándo TIENE QUE cambiar de banco?

¿Fue útil?

Solución

Primero, qué dispositivo de imagen está usando, ya que eso hace una pequeña diferencia. También qué compilador estás usando.

Sin embargo, la razón por la que su código funciona es porque todo lo que necesita hacer para enviar un mensaje al uart está en el banco 0. Sus escrituras al puerto b no están haciendo nada. Supongo que usted quiere cambiar el trisb y está en el banco 1 pero como el uart tiene el control de los pines que escriben en el puerto B, este no tiene ningún efecto. En su segundo ejemplo, está sondeando lo que cree que es TXSTA, pero eso está en el banco 0 no en el banco 1. Supongo que tiene suerte al sondear la ubicación incorrecta y el bit siempre está en el estado correcto, por lo que el bucle termina.

Cuando hago una transmisión, prefiero ver primero si el uart está vacío y esperar hasta que esté y luego enviar el char. No es necesario esperar a que finalice la transmisión, a menos que desee utilizar una interrupción, por ejemplo, para obtener el siguiente carácter.

Así que ambas piezas de código funcionan porque estás en el banco 0 en ambas cuando haces movwf TXREG. El resto se maneja en hardware para usted.

Editar: Ahora que sé la parte en la que está en lo correcto, TXSTA está en el banco 1. Usted a través de mí porque tenía un comentario de la dirección como 0x18 y debería ser 0x98. En el primer ejemplo, está sondeando el bit 1 de RCSTA, que es el OERR no TXSTA. Entonces, si está funcionando, esto implica que OERR = 1, que es muy posible, normalmente lo borro cuando hago algo con la recepción.

Otros consejos

Es mejor usar BANKSEL para cambiar automáticamente su banco. Es una directiva especial para ensambladores que le dice al ensamblador que cambie al banco correcto. Por lo tanto, si desea acceder a PORTB, simplemente BANKSEL (PORTB) antes de usarlo.

PS: PORTB está en BANK0 en la familia PIC16, no en BANK1 como en su código.

A mí también me resultó muy difícil entender la selección del banco.

Estoy iniciando un proyecto utilizando PIC12F1822s, por su funcionalidad I2C. Investigar el fondo es como desenredar una madeja de hilos, cada uno necesita mucha lucha antes de que quede claro. Uno de los hilos que he logrado extraer es una explicación del " BANKSEL " directiva.

Fondo. Hay varias docenas de SFR (Registros de funciones especiales) que ayudan en la operación del dispositivo, asignados a la memoria de datos inferior. Debido a que hay tantos, están organizados en 32 Bancos, numerados del 0 al 31, de 32 SFR cada uno. Los SFR están numerados secuencialmente en la forma (bits) bbbbbfffffff donde bbbbb es el número del banco y fffffff es el desplazamiento en el banco. Sus valores se definen en el archivo .INC para el PIC, y hay muchos huecos en la secuencia. Tenga en cuenta que para las compensaciones de SFR en los bancos 0 a 30 solo son suficientes cinco bits, pero para el banco 31 son necesarios siete bits.

Al acceder a uno de estos SFR, su número de banco debe estar en el registro BSR, que se establece mediante el " MOVLB " instrucciones de ensamblador. Para facilitar esta tarea, existe una directiva " BANKSEL " que se puede utilizar antes de cada acceso de un SFR. (En otros PIC, los bits en el registro de ESTADO retienen el número de banco) Después de una prueba exitosa, cualquier BANKSEL superfluo puede ser eliminado. Mi enigma (después de establecer esto hasta ahora, la información en la documentación es escasa y dispersa) era cómo funciona esta directiva. Por supuesto, es evaluado por el ensamblador antes de que se produzca cualquier código, y este es mi código de prueba para verificarlo, usar EQU para hacer los cálculos y explicarlo (nota locn es " Ubicación " es decir, la dirección del instrucción.):

        ;BANKSEL is a directive that does the equivalent of 
        ;       movlb  (<SFRname> & 0XF0) >> 7

        ;For example TRISA is defined in P12F1822.INC as:

        ;-----Bank1------------------
        TRISA            EQU  H'008C' 

   Assembler:
   Locn   Resulting value     Line  Original code line content ";" is a comment
   ~~~~   ~~~~~~~~~~~~~~~     ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                              00047 ; Test of equivalent of BANKSEL directive          
          0000008C            00048 selbank equ TRISA
          00000080            00049 selbnk1 equ selbank & 0XF80 ; Extract bank no. ..
          00000001            00050 selbnk2 equ selbnk1 >> 7 ; .. move it to the right
          0000000C            00051 selbnk3 equ TRISA & 0XF80 >> 7 
        [ Operator precedence: >> (bit shift right) higher than & (bitwise AND) ]
          0000000C            00052 selbnk4 equ TRISA & (0XF80 >> 7) ; default
          00000001            00053 selbnk5 equ (TRISA & 0XF80) >> 7 ; as needed`
                     . . .
   006C   0021                00100 movlb  1           ; Should be same as next line
   006D   0021                00101 banksel TRISA       
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top