3
\$\begingroup\$

I have a problem while trying to do a Delay on a PIC16LF1823. My program tries to toggle some bits on PORTC for 30ms. I did a simple Delay based on the decrement of a variable; however, each time the PIC execute the Delay it gets stuck on the Delay subroutine forever. I have tried everything and I traced the problem to the DECFSZ instruction (If it is removed the bits toggle without the delay and the program executes normally). Is this a known issue? Or, Am I doing something wrong? My configuration: 31kHz Internal Oscillator. Using MPLAB X and MPASM v5.46. I hope anyone can point me in the right direction; I have been trying to fix this for a week now. Thanks, Here's my code:

    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
\$\endgroup\$
3
  • \$\begingroup\$ You are using BCF and BSF on PORT bits. AFAIK these enhanced PICs still suffer from the read-modify-write 'feature'. If you don't now what that is be sure to look it up!! \$\endgroup\$ Sep 19 '12 at 16:59
  • \$\begingroup\$ Mmmm I don't know if you are talking about the difference between PORT and LAT... If so, while is a better practice to use LAT for Outputs, PORT will have the same effect (Based on the Datasheet); I will change it to LATC anyway, thanks for the observation. \$\endgroup\$ Sep 19 '12 at 19:18
  • \$\begingroup\$ Check DS41413C-page 121, the circuit at the top. The LAT registers read what you have written, the PORT registers read the actual level of the output pin. That can be different. A BCF reads all pins, changes one, and writes back. Hence (for instance) the load on a previously-set pin can cause it to revert to clear. LAT is not just better practice, using PORT with a read-modify-write instruction is very bad programming. \$\endgroup\$ Sep 20 '12 at 6:33
2
\$\begingroup\$

CBLOCK needs a value, otherwise it will be zero, and the variable won't be in in RAM. Set it to 0x20, which puts it at the start of the General Purpose RAM block.

I can't see anything wrong with your delay routine and it worked OK when I simulated it to make sure, with CBLOCK set to 0x20.

Remove the CLRWDT instruction and disable the WDT.

Put

d1 res 1

at the end of your program if you want to use Olin's preferred technique.

\$\endgroup\$
2
  • \$\begingroup\$ CBLOCK does not allocate variables. That's what RES is for. CBLOCK is only for creating a related set of enumerated constants. Sometimes people abuse CBLOCK to create a bunch of symbols that then only they know (not the assembler or linker) stand for addresses of variables. This is REALLY BAD PRACTISE. \$\endgroup\$ Sep 19 '12 at 13:38
  • \$\begingroup\$ Leon, thanks for the answer; I knew something was missing on that declaration. However, it works with the WDT; there is no need to remove it. \$\endgroup\$ Sep 19 '12 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.