DECFSZ no funcionará en PIC16LF1823

Tengo un problema al intentar hacer un Delay en un PIC16LF1823. Mi programa intenta alternar algunos bits en PORTC durante 30 ms. Hice un Delay simple basado en el decremento de una variable; sin embargo, cada vez que el PIC ejecuta el Retraso, se atasca en la subrutina Delay para siempre. Intenté todo y rastreé el problema a la instrucción DECFSZ (si se elimina, los bits se alternan sin demora y el programa se ejecuta normalmente). ¿Es este un problema conocido? O, ¿estoy haciendo algo mal? Mi configuración: oscilador interno de 31 kHz. Utilizando MPLAB X y MPASM v5.46. Espero que alguien pueda indicarme la dirección correcta; He estado tratando de arreglar esto durante una semana. Gracias, aquí está mi código:

    INCLUDE "P16F1823.inc"

; CONFIG1
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_NSLEEP & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
; CONFIG2
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_ON

org 0x00
GOTO Start
org 0x04
GOTO Interrupt

#Define LCK 0x01
#Define LTC 0x04
#Define RLS 0x05

IOA EQU B'00000011'
IOC EQU B'00000000'
IOP EQU B'00000011'
ION EQU B'00000010'
INT EQU B'10001000'
OSC EQU B'00000000'
OPT EQU B'11010000'

CBLOCK
d1
ENDC

;;;;;;;;;;;;;;;;;;
;;INITIALIZATION;;
;;;;;;;;;;;;;;;;;;
Start
BANKSEL PORTA
CLRF PORTA
BANKSEL LATA
CLRF LATA
BANKSEL ANSELA
CLRF ANSELA
BANKSEL TRISA
MOVLW IOA
MOVWF TRISA

BANKSEL PORTC
CLRF PORTC
BANKSEL LATC
CLRF LATC
BANKSEL ANSELC
CLRF ANSELC
BANKSEL TRISC
MOVLW IOC
MOVWF TRISC

BANKSEL OSCCON
MOVLW OSC
MOVWF OSCCON

BANKSEL OPTION_REG
MOVLW OPT
MOVWF OPTION_REG

BANKSEL INTCON
MOVLW INT
MOVWF INTCON
BANKSEL IOCAP
MOVLW IOP
MOVWF IOCAP
BANKSEL IOCAN
MOVLW ION
MOVWF IOCAN

CLRF BSR
;;;;;;;;;;;;;;;;;;
;; MAIN PROGRAM ;;
;;;;;;;;;;;;;;;;;;
Loop
CALL Toggle
GOTO  Loop
;;;;;;;;;;;;;;;;;;
;;  INTERRUPTS  ;;
;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;
;; SUBROUTINES  ;;
;;;;;;;;;;;;;;;;;;
Toggle
   ;; LATCH ;;
CLRWDT
BSF  PORTC,LTC
CALL Delay30ms
BCF  PORTC,LTC
   ;; WAIT ;;
CALL Delay30ms
   ;;RELEASE;;
BSF  PORTC,RLS
CALL Delay30ms
BCF  PORTC,RLS
   ;; EXIT ;;
RETURN

Delay30ms
MOVLW   0x4C
MOVWF   d1
D30Loop
CLRWDT
DECFSZ  d1, f
GOTO D30Loop
RETURN
;;;;;;;;;;;;;;;;;;
;;END OF PROGRAM;;
;;;;;;;;;;;;;;;;;;
END
Está utilizando BCF y BSF en bits de PUERTO. AFAIK estos PIC mejorados todavía sufren de la 'característica' de lectura-modificación-escritura. Si no sabes lo que es, ¡asegúrate de buscarlo!
Mmmm, no sé si está hablando de la diferencia entre PORT y LAT... Si es así, aunque es una mejor práctica usar LAT para salidas, PORT tendrá el mismo efecto (según la hoja de datos); Lo cambiaré a LATC de todos modos, gracias por la observación.
Verifique DS41413C-página 121, el circuito en la parte superior. Los registros LAT leen lo que ha escrito, los registros PORT leen el nivel real del pin de salida. Eso puede ser diferente. Un BCF lee todos los pines, cambia uno y vuelve a escribir. Por lo tanto, (por ejemplo) la carga en un pin previamente establecido puede hacer que se vuelva a despejar. LAT no es solo una mejor práctica, usar PORT con una instrucción de lectura, modificación y escritura es una programación muy mala.

Respuestas (1)

CBLOCK necesita un valor, de lo contrario será cero y la variable no estará en la RAM. Establézcalo en 0x20, lo que lo coloca al comienzo del bloque de RAM de propósito general.

No puedo ver nada malo con su rutina de retraso y funcionó bien cuando lo simulé para asegurarme, con CBLOCK configurado en 0x20.

Elimine la instrucción CLRWDT y deshabilite el WDT.

Poner

d1 resolución 1

al final de su programa si desea utilizar la técnica preferida de Olin.

CBLOCK no asigna variables. Para eso está el RES. CBLOCK es solo para crear un conjunto relacionado de constantes enumeradas. A veces, las personas abusan de CBLOCK para crear un montón de símbolos que solo ellos conocen (no el ensamblador o el enlazador) representan direcciones de variables. Esto es REALMENTE MALA PRÁCTICA .
León, gracias por la respuesta; Sabía que faltaba algo en esa declaración. Sin embargo, funciona con el WDT; no hay necesidad de quitarlo.