Countup OK but Countdown Problem

Status
Not open for further replies.

Suraj143

Active Member
Here is the coding for my count up in the two seven segments. It’s working perfectly.
(Data lookup table starting from retlw 0 to 9)
Code:
COUNTUP     incf  DIGIT1,1		;increase digit1
	  	movlw 0AH		;check whether it has reach ten
	  	xorwf DIGIT1,w	       ;compare
	  	btfss STATUS,Z
	  	goto  MULTIPLEX
	  	clrf  DIGIT1
	  	incf  DIGIT2,1	;increase digit2
	  	movlw 0AH		;check whether it has reach ten
	  	xorwf DIGIT2,w	;compare
	  	btfsc STATUS,Z
	  	clrf  DIGIT2 
		goto  MULTIPLEX

Here is the coding for my count down in the two seven segments. But this is not working.
All the time it’s showing “99” (Data lookup table starting from retlw 9 to 0)

Code:
COUNTUP     decf  DIGIT1,1	;decrease digit1
	  	movlw 00H		;check whether it has reach zero
	  	xorwf DIGIT1,w	;compare
	  	btfss STATUS,Z
	  	goto  MULTIPLEX
	  	clrf  DIGIT1
	  	decf  DIGIT2,1	;decrease digit2
	  	movlw 00H		;check whether it has reach zero
	  	xorwf DIGIT2,w	;compare
	  	btfsc STATUS,Z
	  	clrf  DIGIT2 
		goto  MULTIPLEX

Can somebody tell what’s wrong with countdown?
 
See comments in following code.

Code:
COUNTDOWN     decf  DIGIT1,1	;decrease digit1

	  	movlw FFH		;check whether it has reach FF
	  	xorwf DIGIT1,w	       ;compare

	  	btfss STATUS,Z
	  	goto  MULTIPLEX

                movlw  9
	  	movwf  DIGIT1        ;set digit1 to 9
   
	  	decf  DIGIT2,1	;decrease digit2

	  	movlw FFH	;check whether it has reach FFH
	  	xorwf DIGIT2,w	;compare

	  	btfss STATUS,Z

		goto  MULTIPLEX

                movlw 9
	  	movwf  DIGIT2    ; set digit2 back to 9
 
Last edited:
Notice the use of "F" and "W" for file destinations?

Code:
COUNTDOWN
	DECF  	DIGIT1, F	;DECREASE DIGIT1
	MOVLW 	.255		;CHECK WHETHER IT HAS UNDERFLOWED
	XORWF 	DIGIT1, W	;COMPARE
	BTFSS 	STATUS, Z
	GOTO  	MULTIPLEX
	MOVLW	.9
	MOVWF	DIGIT1
	DECF  	DIGIT2, F	;DECREASE DIGIT2
	MOVLW 	.255		;CHECK WHETHER IT HAS UNDERFLOWED
	XORWF 	DIGIT2, W	;COMPARE
	BTFSS 	STATUS, Z
	GOTO	MULTIPLEX
	MOVLW	.9
	MOVWF	DIGIT2
	GOTO  	MULTIPLEX

eblc1388 beated me to it because of this slow slow forum. Takes me all day to upload a post

However, I ran both our versions through MPLAB SIM and ecblc1388's code does not display "99". It displayS "01,00,98" because the "99" condition is not multiplexed. So all you have to do is add one more GOTO MULTIPLEX like my above code. Case closed and new post needed not.
 
Last edited:
You can replace
Code:
	MOVLW 	.255		;CHECK WHETHER IT HAS UNDERFLOWED
	XORWF 	DIGIT1, W	;COMPARE
	BTFSS 	STATUS, Z
With
Code:
	BTFSS 	DIGIT1,7

This is how I suggested the OP did it in his previous thread.

Mike.
 
Not sure if a "packed BCD" variable would be an advantage or not but thought it might be worth mentioning. Also, I apologize in advance if this example seems a little overwhelming.

A single "packed BCD" variable could be used for your 2-digit 00..59 value and here's one way you might handle the count down function (packed BCD arithmetic);

Code:
;
;  2-digit count down timer, stop at 0
;
;  if (seconds != 0)
;    seconds--;
;
        movf    seconds,W       ; seconds = 00, all done?
        bz      next            ; yes, branch, else
        addlw   -1              ; decrement counter
        skpdc                   ; if 4F, 3F, 2F, etc
        addlw   -6              ; make it 49, 39, 29, etc
        movwf   seconds         ; save it
next
;
Code:
;
;  2-digit count down timer, cyclic
;
;  if (seconds == 0)
;    seconds = 60;
;  seconds--;
;
        movf    seconds,W       ; seconds = 00?
        skpnz                   ; no, skip, else
        movlw   h'60'           ; change to 60
        addlw   -1              ; decrement counter
        skpdc                   ; if 5F, 4F, 3F, etc
        addlw   -6              ; make it 59, 49, 39, etc
        movwf   seconds         ; save it
;
It's also very easy to extract the individual digits from a packed BCD variable;

Code:
;
        swapf   seconds,W       ; hi nybble in bits 3..0
        andlw   h'0F'           ; W = tens digit, 0..9

        movf    seconds,W       ; lo nybble in bits 3..0
        andlw   h'0F'           ; W = ones digit, 0..9
Finally, a full-blown Photo Timer or Appliance Timer might use a similar algorithm and a 3 element array for Hours, Minutes, and Seconds (the array elements can be accessed directly in your MAIN program as TMRHRS, TMRMIN, and TMRSEC);

Code:
;
;  unsigned char Timer [] = { 23, 00, 00 };  // hrs, mins, secs.
;
;  if (TimerEnabled)            // if Count Down Timer enabled
;  { unsigned char n = 2;       // index seconds array element
;    while (!Timer[n]--)        // while value 00 (post dec value)
;    { Timer[n--] = 59;         // set to 59 and bump array index
;    }                          // turn off timer when timed-out
;    if(!(TimerEnabled = Timer[0]|Timer[1]|Timer[2]))
;    {                          // perform timed-out code here
;    }
;  }
;
ISR_TMR
        btfss   SW.TMR          ; timer switch turned on?         |B0
        goto    ISR_Next        ; no, branch, else                |B0
        movlw   TMRSEC          ;                                 |B0
        movwf   FSR             ; setup indirect access           |B0
ISR_T0
        movf    INDF,W          ; array element = 00?             |B0
        bnz     ISR_T1          ; no, branch, else                |B0
        movlw   h'59'           ;                                 |B0
        movwf   INDF            ; reset to '59'                   |B0
        decf    FSR,f           ; decrement array index           |B0
        goto    ISR_T0          ; test next array element         |B0
ISR_T1
        addlw   -1              ; post decrement element          |B0
        skpdc                   ;                                 |B0
        addlw   -6              ;                                 |B0
        movwf   INDF            ;                                 |B0
        movf    TMRHRS,W        ; check for time-out              |B0
        iorwf   TMRMIN,W        ;                                 |B0
        iorwf   TMRSEC,W        ; TMR = 00:00:00?                 |B0
        skpnz                   ; no, skip, else                  |B0
        bcf     SW.TMR          ; turn timer switch off           |B0
;
ISR_Next
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…