Evitar múltiples definiciones usando el efecto secundario de la banca PIC

0

Esta es más una cuestión de estilo que cualquier otra cosa y podría parecerle algo malo a algunos. Si tengo un pin de puerto serie en RC4, digamos, puedo hacer algunas definiciones para ayudar:

#define TXSER_PIN   LATC, RC4

Lo que me doy cuenta entonces es que puedes hacer esto:

banksel     LATC
bsf         TXSER_PIN
banksel     ANSELC
bcf         TXSER_PIN
banksel     TRISC
bcf         TXSER_PIN
banksel     INLVLC
bsf         TXSER_PIN 

Estoy usando la misma definición hasta el final aunque, en teoría, supongo que es incorrecto hacerlo. El punto es que puedo cambiar LATC, RC4 a LATB, RB7 y (después de cambiar también APFCON0 para mover la función de TX) eso es todo lo que cambia.

En este PIC que estoy usando, TRISA = 0x8C y LATA = 0x10C . Pero solo BANKSEL hace que sean distinguibles: TRISA, LATA, ANSELA, WPUA son en realidad todos el mismo desplazamiento 0x0C desde el inicio del banco y, al compilar la instrucción implícitamente, un "operando & 0xFF" puede usarse. indistintamente.

(De hecho, eso puede ser bastante molesto si usas pares de operandos incorrectamente. Algo como bsf EEADRL, RC5 no marcará un error a pesar de que el compilador podría hacerlo fácilmente. Escribí algunos awk para detectar esto ...)

¿Puedo tener problemas al hacer esto o es simplemente una mala forma? Claro que hace menos #defines aunque.

    
pregunta carveone

2 respuestas

2

Al final del día, el ensamblador no tiene una pista sobre #defines.

El ensamblador ni siquiera llega a verlos. El preprocesador primero escanea el archivo expandiendo #defines (denominadas macros del preprocesador ) y los convierte en los números que representan. Así que el ensamblador solo obtiene números.

Entonces no, el ensamblador no puede entender si

bsf EEADRL, RC5

es válido o no, ya que nunca llega a ver eso. El preprocesador no tiene un concepto de sintaxis de ensamblador o qué significan los diferentes símbolos, por lo que no puede saber si está mal.

En mi opinión, las macros siempre deberían decir lo que significan. Mientras el contenido de la macro se expanda a los valores correctos, realmente no importa lo que digan las macros provisionales. Si la macro TXSER_PIN tiene un significado contextual válido para la persona que lee el código en ese momento, no hay razón para usarlo. Si no es así, utiliza una macro que tenga significado.

Después de todo, una macro es puramente una representación humana de números u otros bits de código / datos, para hacer que el código sea más legible.

No ocupan espacio en flash o ram, por lo que puedes tener tantos como quieras.

Es más importante pensar en agrupar las operaciones SFR que están en el mismo banco para reducir el número de llamadas banksel , ya que cada una toma ciclos flash y de CPU que podrían usarse en otros lugares.

    
respondido por el Majenko
2

Es ciertamente posible aprovechar el hecho de que varias direcciones difieren solo en los bits de selección de banco. Sin embargo, generalmente evitaría hacerlo, ya que el código escrito de tal manera puede ser difícil de portar a chips donde las direcciones de los registros tienen relaciones diferentes entre sí. Aunque Microchip ha sido bastante bueno al continuar produciendo partes que pueden ejecutar código más antiguo, la migración de diseños a partes más nuevas a menudo puede generar importantes ahorros de costos.

Uno de los trucos que he usado en lenguaje ensamblador en el PIC 16C505, por cierto, que no habría funcionado en C, fue escribir un "tasador dual" cooperativo que usaba una pieza de código para manejar series en serie. E / S con PORTB, y otra pieza de código para manejarlo con PORTC. Las variables globales se mantuvieron en la RAM "no bancarizada", y las variables por tarea en la RAM "acumulada". El bucle principal parecía algo así como:

bucle:     llamada trampolín     movwf tempPC; RAM depositada     movlw 0x21     xorwf FSR; Los bits 0-4 de FSR apuntan a PORTB o PORTC; bit 5 sets banco de RAM     movf tempPC, w     goto loop trampolín:     movwf PC

Cada tarea ejecutaría un poco de código y luego realizaría un RETLW con la dirección del siguiente fragmento de código que debería ejecutar. La mayoría de la ROM estaba ocupada por un código que a veces funcionaría en PORTB utilizando un conjunto de variables y, a veces, en PORTC, utilizando el otro conjunto. El efecto general fue algo así como un ahorro de código del 40% en comparación con tener que usar dos conjuntos de códigos separados.

    
respondido por el supercat

Lea otras preguntas en las etiquetas