¿Cuál es la forma más efectiva de guardar / restaurar un bit de estado PIC?

5

Quiero guardar / restaurar el bit de acarreo del PIC. Estoy usando el 16F628A.

SAVE_CARRY
    btfss STATUS, 0
    goto CARRY_OFF 

CARRY_ON
    bsf carry, 0
    return

CARRY_OFF
   bcf carry, 0
   return

RESTORE_CARRY
   btfss carry, 0
   goto RESTORE_CARRY_OFF

RESTORE_CARRY_ON
   bsf STATUS, 0
   return

RESTORE_CARRY_OFF
   bcf STATUS, 0
   return

Debe haber una mejor manera. Hay?

    
pregunta mmccoo

2 respuestas

5

Una forma de hacerlo:

SAVE_CARRY:
    bsf    carry, 0
    btfss  status, c
    bcf    carry, 0
    return

RESTORE_CARRY
    bsf    status, c
    btfss  carry, 0
    bcf    status, c
    return

Si necesita guardar los registros "W" y "Estado", antes de ejecutar un código de interrupción, existe otra forma:

Save_Context:
    movwf w_temp
    swapf status,w
    movwf status_temp
    ;Your interrupt code here. 

Restore_Context:
    swapf status_temp,w
    movwf status
    swapf w_temp,f
    swapf w_temp,w
    retfie
    
respondido por el Daniel Grillo
3

Si solo desea guardar / restaurar el bit de acarreo, y si no le importa perder el valor cuando lo almacena y destruye el valor guardado cuando lo restaura, simplemente use "rlf saved_carry, f" para guardarlo y "rrf saved_carry, f" para restaurarlo. No hay otros registros o banderas afectadas.

Si la velocidad es de suma importancia y necesita guardar / configurar otro bit y restaurarlo más tarde (por ejemplo, RP0), puede hacer algo como:

Int_Entry:
  btfss STATUS,RP0
   goto Version_with_RP0_clear
  bcf   STATUS,RP0
  do_interrupt_logic
  bsf   STATUS,RP0
  retfie
Int_with_RP0_Clear:
  do_interrupt_logic
  bcf   STATUS,RP0 ; If interrupt logic might have left it set
  retfie

Eso es un total de cuatro ciclos no solo para guardar / restaurar RP0, sino también para establecer un estado conocido para el ISR (si se toma la rama, RP0 ya está en el estado correcto, por lo que no es necesario configurarlo) . Si la lógica de interrupción no afectaría a W u otros indicadores (por ejemplo, si usa bsf / bcf / btfss / btfsc / incfsz / decfsz para casi todo), esta lógica puede guardar cuatro ciclos en lugar de guardar W y estado, borrar el estado, ejecutar el interrumpir, y luego restablecer el estado y W. Estos ahorros no son importantes en muchos casos, pero pueden ser muy importantes si uno intenta, por ejemplo, use una interrupción TMR2 para hacer algo cada 50 ciclos. Como TMR2IF está en un registro bancado, uno tiene que borrar RP0 para restablecer TMR2IF. Si TMR2 está marcando cada 50 ciclos y el ISR tomaría 26 ciclos con la mejora o 30 ciclos sin, guardar esos tres ciclos en el ISR podría aumentar la disponibilidad de la CPU de la línea principal en un 20%.

    
respondido por el supercat

Lea otras preguntas en las etiquetas