MACROS

Utilizando estas macros podrás contar con instrucciones nuevas que agilizan la programación y la hacen un poco más ordenada.
No todo es color de rosa...el utilizar macros también es peligroso. Hay ciertas limitaciones y condiciones a tener en cuenta para no cometer errores.

Desventajas de usar macros:

Una MACRO no es nada menos que una serie de instrucciones que realizan una determinada tarea y que la llamamos por medio de un nombre nuevo que implica esa acción a realizar. Pero cuidado!!!, no es una subrutina ni una nueva instrucción del microprocesador.

Veamos un ejemplo de lo que NO SE DEBE HACER:


copyLF

;Esta macro copia un literal a un registro:
macro lit,reg
movlw lit
movwf reg
endm
; . . .
btfss  STATUS,Z       ; NUNCA HACER ESTO !!!!
copyLF 3,TEMP         ;   "     "    "
goto   FIN
; . . .

En este ejemplo, se pretende "saltar" una macro con unna instrucción de SKIP...No, no, NO...!
Nunca utilices instrucciones de SKIP si vas a utilizar macros. Para evitar este inconveniente tenes que usar macros de saltos que hagan este trabajo por vos.

Esta opción te la doy aca en este archivo de macros super útiles, pero antes algunas explicaciones del caso:

_Temp y _TempInt son son dos variables temporales. Una se puede usar desde una interrupcion.

Safe_DI: esta macro espera que el bit de inabilitacion este seteado antes de seguir.

PushAll y PopAll: las uso dentro de una interrupcion para salvar los registros y el status.
Ejemplo:

interrup:

PushAll
;.....
;programa de interrupcion
;.....
PopAll
RETFIE

INIT_TIMER y RESET_TIMER:
con INIT_TIMER inicializo el timer antes de hacer RESET_TIMER para que arranque por ejemplo, dentro de una interrupcion:

interrup: INIT_TIMER 124 ; cargo el contador con un valor
RESET_TIMER    ; y arranca!
retfie

SwitchW y SwitchF: salta al offset especificado en W o en F, a partir de esta macro.
por ejemplo:

movlw .2 ; salta a 'dos'
SwitchW
goto uno
goto dos
goto tres
goto cuatro ; w nunca debe ser mayor que la cantidad de GOTOs

New: crea una variable en una posición de memoria libre.
ejemplo:

New contador
copyLF 3,contador
New temp1
movwf temp1

Alloc <Size>: reserva 'Size' cantidad de espacio de memoria RAM.
reserva el espacio igual que new pero más de un byte.
ejemplo:

Alloc 10 ; reserva 10 pos de mem.

el proximo new tomara 10 direcciones mas arriba.

copyBit: copia un bit de un registro en otro bit de otro registro.
ejemplo:

copyBit STATUS,C, PORTB,5

 

MACROSPIC.ASM

;-----------------------------------------------------------------------------
; macrospic.asm
;
; Version: 1.0
; Inicialización: 11/07/2002
; Actualización:
; Programador: Javier Rambaldo
; Observaciones: MACROS para 16F84
;
;-----------------------------------------------------------------------------

#include "p16f84a.inc"

;-----------------------------------------------------------------------------
; todos los proyectos usan este RAM-TOP y estas variables.
;-----------------------------------------------------------------------------
_w_temp equ 0x0C ; para salvar registros en interrupcion
_status_temp equ 0x0D ; "
__DAvail set 0x0E ; primera pos de mem.
__RAMTop set 0x4F ; ultima pos de mem.

;-----------------------------------------------------------------------------
; *** MACROS ***
;-----------------------------------------------------------------------------

; ojo! para usar estas macros ya debe estar seteado el banco 1 !!!
CONF_PORTA macro dato
    movlw dato
    movwf TRISA
    endm

CONF_PORTB macro dato
    movlw dato
    movwf TRISB
    endm

CONF_OPTION macro dato ; configuro el Option Register
    movlw dato
    movwf OPTION_REG
    endm

CONF_INTCON macro dato ; configuro el registro de interrupciones
    movlw dato
    movwf INTCON
    endm

; enable y disable all the mascarable interrupts (16F84):
#define EI BSF INTCON,GIE
#define DI BCF INTCON,GIE

; me aseguro que no ocurra una interrupcion justo cuando la estoy inhabilitando...
Safe_DI macro
    local _sfdi
_sfdi bcf INTCON,GIE
    btfsc INTCON,GIE
    goto _sfdi
    endm

PushAll macro ; salvo todos los registros en interrupcion
    movwf _w_temp
    swapf STATUS,w
    movwf _status_temp
    endm

PopAll macro ; recupero todos los registros en interrupcion
    swapf _status_temp,w
    movwf STATUS
    swapf _w_temp,f
    swapf _w_temp,w
    endm

BANK0 macro
    BCF STATUS,RP0
    endm

BANK1 macro
    BSF STATUS,RP0
    endm

EnableInts macro
    BSF INTCON,GIE
    endm

DisableInts macro
    BCF INTCON,GIE
    endm

EnableTMR0Int macro
    BSF INTCON,T0IE
    endm

EnableRB0Int macro
    BSF INTCON,INTE
    endm

EnableRBInt macro
    BSF INTCON,RBIE
    endm

DisableTMR0Int macro
    BCF INTCON,T0IE
    endm

DisableRB0Int macro
    BCF INTCON,INTE
    endm

DisableRBInt macro
    BCF INTCON,RBIE
    endm

RESET_RBO macro
    BCF INTCON,INTF
    endm

RESET_RB macro
    BCF INTCON,RBIF
    endm

RESET_TIMER macro ; arranca el timer
    bcf INTCON,T0IF
    endm

INIT_TIMER macro dato ; inicializo el timer antes de hacer RESET_TIMER para que arranque
    movlw dato
    movwf TMR0
    endm

;=================================================

djnz macro reg,salto ; decrementa y salta si no zero (3+1 ciclos)
    decfsz reg,f
    goto salto
    endm

jz macro _salto ; salta si zero
    btfsc STATUS,Z
    goto _salto
    endm

jnz macro _salto ; salta si no zero
    btfss STATUS,Z
    goto _salto
    endm

jc macro _salto ; salta si carry
    btfsc STATUS,C
    goto _salto
    endm

jnc macro _salto ; salta si no carry
    btfss STATUS,C
    goto _salto
    endm

jmp macro jujuy ; salta siempre (jujuy tambien!)
    goto jujuy
    endm

jbs macro FILE,BIT,SALTO ; Jump if Bit Set
    btfsc FILE,BIT
    goto SALTO
    endm

jbc macro FILE,BIT,SALTO ; Jump if Bit Clear
    btfss FILE,BIT
    goto SALTO
    endm

inc macro reg
    incf reg,f
    endm

dec macro reg
    decf reg,f
    endm

cmplf macro _k,_f ; hace pelota W !
    movlw _k
    subwf _f,w ; reg - k => W ; si k>reg => C=0
    endm

cmpff macro f1,f2 ; comparo dos registros
    movf f2,w ; f1-f2
    subwf f1,w
    endm

testf macro reg
    movf reg,f
    endm

; Jump Equal, Not Equal, Less Than, Greater Than:
#define jeq jz
#define jne jnz
#define jlt jnc
#define jge jc

comw macro ; complemento a 1 de W
    xorlw 0xff
    endm

movff macro orig,dest ; OJO que modifica W y STATUS!
    movf orig,w
    movwf dest
    endm

movlf macro literal,dest
    movlw literal
    movwf dest
    endm

copyBit macro f_orig,b_orig,f_dest,b_dest
    btfss f_orig,b_orig
    bcf f_dest,b_dest
    btfsc f_orig,b_orig
    bsf f_dest,b_dest
    endm

SwitchW macro ; salta al offset especificado en W (desde la macro)
    local TableStart
    clrf PCLATH
    if((HIGH TableStart) & 1 ) == 1
    bsf PCLATH,0
    else
    bcf PCLATH,0
    endif
    if((HIGH TableStart) & 2 ) == 2
    bsf PCLATH,1
    else
    bcf PCLATH,1
    endif
    addlw LOW(TableStart)
    skpnc
    incf PCLATH,f
    movwf PCL
TableStart:
    endm

SwitchF macro reg
    local TableStart2
    clrf PCLATH
    if((HIGH TableStart2) & 1 ) == 1
    bsf PCLATH,0
    else
    bcf PCLATH,0
    endif
    if((HIGH TableStart2) & 2 ) == 2
    bsf PCLATH,1
    else
    bcf PCLATH,1
    endif
    movf reg,w
    addlw LOW(TableStart2)
    skpnc
    incf PCLATH,f
    movwf PCL
TableStart2:
    endm

New macro Name ; crea una variable:
    NoExpand
    if __DAvail > __RAMTop
    Error "No hay más memoria o registros disponibles"
    endif
Name equ __DAvail
__DAvail = __DAvail + 1
    Expand
    endm

Alloc macro Size ; reserva 'Size' cantidad de espacio de memoria RAM:
    NoExpand
__DAvail = __DAvail + Size
    if __DAvail > __RAMTop
    Error "No hay más memoria o registros disponibles"
    endif
    Expand
    endm

;------------------------------------------------
movlf16 macro k16,f16
    movlw HIGH(k16)
    movwf f16
    movlw LOW(k16)
    movwf f16+1
    endm

;------------------------------------------------
movff16 macro f1,f2
    movf f1,w
    movwf f2
    movf f1+1,w
    movwf f2+1
    endm

;------------------------------------------------
incf16 macro f16
    local _fin
    incfsz f16+1,f
    goto _fin
    incf f16,f
_fin
    endm

;------------------------------------------------
if16jz macro f16,_salto
    local _fin
    incfsz f16+1,f
    goto _fin
    incfsz f16,f
    goto _fin
    goto _salto
_fin
    endm

;------------------------------------------------
if16jnz macro f16,_salto
    local _fin
    incfsz f16+1,f
    goto _salto
    incfsz f16,f
    goto _salto
_fin
    endm

;------------------------------------------------
decf16 macro f16
    movf f16+1,f
    btfsc STATUS,Z
    decf f16,f
    decf f16+1,f
    movf f16,w
    iorwf f16+1,w
    endm

;------------------------------------------------
df16jnz macro f16,_salto
    movf f16+1,f
    btfsc STATUS,Z
    decf f16,f
    decf f16+1,f
    movf f16,w
    iorwf f16+1,w
    btfss STATUS,Z
    goto _salto
    endm

;------------------------------------------------
df16jz macro f16,_salto
    movf f16+1,f
    btfsc STATUS,Z
    decf f16,f
    decf f16+1,f
    movf f16,w
    iorwf f16+1,w
    btfsc STATUS,Z
    goto _salto
    endm

;------------------------------------------------
clrf16 macro f16
    clrf f16
    clrf f16+1
    endm

;------------------------------------------------
rlf16 macro f16
    rlf f16+1,f
    rlf f16,f
    endm

;------------------------------------------------
rrf16 macro f16
    rrf f16,f
    rrf f16+1,f
    endm

;------------------------------------------------
slf16 macro f16
    rlf f16+1,f
    rlf f16,f
    bcf f16+1,0
    endm

;------------------------------------------------
srf16 macro f16
    rrf f16,f
    rrf f16+1,f
    bcf f16,7
    endm

;------------------------------------------------
slf macro f8
    rlf f8,f
    bcf f8,0
    endm

;------------------------------------------------
srf macro f8
    rrf f8,f
    bcf f8,7
    endm

;------------------------------------------------
rlncf macro f8
    rlf f8,f
    btfsc STATUS,C
    bsf f8,0
    btfss STATUS,C
    bcf f8,0
    endm

;------------------------------------------------
rrncf macro f8
    rrf f8,f
    btfsc STATUS,C
    bsf f8,7
    btfss STATUS,C
    bcf f8,7
    endm

;------------------------------------------------
swapf16 macro _x,_y
    movf _y,w
    xorwf _x,f
    movf _x,w
    xorwf _y,f
    movf _y,w
    xorwf _x,f
    endm

;------------------------------------------------
decw macro
    addlw 0xff
    endm

;------------------------------------------------
incw macro
    addlw 0x01
    endm

;------------------------------------------------
dwjz macro _salto
    addlw 0xff
    btfsc STATUS,Z
    goto _salto
    endm

;------------------------------------------------
iwjz macro _salto
    addlw 0x01
    btfsc STATUS,Z
    goto _salto
    endm

;------------------------------------------------
dwjnz macro _salto
    addlw 0xff
    btfss STATUS,Z
    goto _salto
    endm

;------------------------------------------------
iwjnz macro _salto
    addlw 0x01
    btfss STATUS,Z
    goto _salto
    endm

;---------------------------------------------------------------
;---------------------------- FIN ------------------------------
;---------------------------------------------------------------