Shop OBEX P1 Docs P2 Docs Learn Events
Decrementing a 4 digit display — Parallax Forums

Decrementing a 4 digit display

BanditBandit Posts: 12
edited 2008-03-02 21:50 in General Discussion
I need help with my timer code: I am trying to decrement a 4 digit LCD display from 90.00 minutes to 0 but the display goes from 1 to 9 with out going through zero.
For example 51 seconds to 49 seconds and from 11 it jumps back to 59.
Code displayed below. Any help would be greatly appreciated.

' File Timer_RevC.SXB
' Purpose multi use timer
' November 25, 2007
'*******************************************************************************************************************
DEVICE SX28,OSCXT2, TURBO, STACKX, OPTIONX, 'BOR26 ' OSCHS3 HIGH SPEED OSCILLATOR BOR26 Brown out reset
'IRC_CAL IRC_SLOW ' TURBO RUNS 4X FASTER THAN COMPATIBILITY MODE.
FREQ 20_000_000 'was 40_000_000 ' IRC_CAL calibrates the internal oscillator. SETS THE INTERNAL OSCILLATOR TO IT'S SLOWEST VALUE
ID "C_Down" ' SETS THE STARTING POINT OF THE PROGRAM FOR THE ASSEMBLER
' 50 kHz
'
Pin assignments

Go PIN RA.1 ' start button
Clear PIN RA.0 ' clear button

DigCtrl PIN RB
Segments PIN RC OUTPUT

AtFinish PIN RB.0 ' Comparator output bit
'
' CONSTANTS
'
Yes CON 1 ' for active-high inputs
No CON 0
M_STOP CON 1 ' clock stopped
M_RUN CON 1 ' clock running
M_CLEAR CON 0 ' clock clear and stopped

NumDigits CON 5'5
'***************************************
DecPnt CON %10000000 ' five digit display
' *************************************
'
Variables
ops VAR BYTE ' operational mode
digPntr VAR Byte ' digital pointer
display VAR Byte(NumDigits) ' cuttent display segments

'*************************************
ms VAR Word 'milliseconds digit
clock Var Byte(5)
MM03 VAR Byte(1) 'hundredths digit
MM02 VAR Byte(1)
MM01 VAR Byte(1) 'tenths digit
sec VAR Byte(1) 'ones digit
sec10 VAR Byte(1) 'tens digit

'blink Var secs.0


'************************************************
' THE COMPARE STATEMENT SETS RB.1 AND RB.2 AS INPUTS AND SETS RB.0 AND _PARAM1 TO 0 IF RB.1 > RB.2.
' So if the opt isolater is blocked RB.1 > RB.2. The LED lights and the timer stops due to _PARAM1 going high and
' setting to G0 = M_Stop
' Start interrupt routine no code before this routine

INTERRUPT 1000 'Rate 1000 ' CHECK ISR EVERY MILLISECOND
GOTO INT_HANDLER

'****************************************************************
PROGRAM Start
'****************************************************************
'
' Subroutine Declarations
'
UPDATE_DISPLAY SUB 0 ' Convert digits to segments

'
' Program Code
'
Start:

DigCtrl = %11111111
TRIS_B = %00000111 '0 'was %00000111 CATHODE PINS SET TO OUTPUT Register B; Rb.0 Rb.1 Rb.2 are inputs Rb.3 thru Rb.7 are outputs
PLP_A = %00000011 ' pull up the unused pins on RA. Ra.0 & Ra.1 the weak pull up resistor is disable.

COMPARE 1, __PARAM1 ' STARTS THE COMPARATOR IN MODE 1; MONITORS rb.1 AND RB.2 OUTPUTS TO RB.0 to see if the optp isolator is blocked

ms = 1000
SEC10 = 9 'was 10 'A
SEC = 5 'second digit 'was 6
MM01 = 9 'was 10 'A
MM02 = 5 '6 59 minutes and 60 seconds
MM03 = 0

ops = M_Clear
' adjust Potentiometer to fine tune comparison. Opto isolator is = 5 volts __Param1 = 0 "two underscores before Param1.
Main:
DO 'ops sets the three mode of operation 0) stopped and cleared 1)running
' 2) stopped; ops is set in the interrupt routine
UPDATE_DISPLAY
IF Go = Yes THEN ' go button pressed
IF ops = M_CLEAR THEN ' were we cleared
ops = M_RUN ' yep so we can run
ENDIF
ENDIF
IF Clear = Yes THEN ' clear button pressed
IF ops = M_STOP THEN
PUT @ms, 0, 5, 9, 5, 9 'was 0000
ops = M_CLEAR ' clear the clock
ENDIF
ENDIF ' refresh segment array

LOOP
'
' Subroutine Code
'

INT_HANDLER:
IF ops <> M_RUN THEN Next_Digit 'skip update if stopped ---OPS HOLDS THE CURRENT THREE STATUS OF TIMER -
' STOPPED AND CLEAR, RUNNING AND STOPPED
Update_Clock:
DEC ms ' increment millisecond display
IF ms = 0 THEN ' CHECKS TO SEE IF WE NEED TO WRAP BACK TO ZERO
ms = 1000 ' was 100
DEC sec10 ' increment hundredth display
IF sec10 = 10 THEN ' 9 DOESN'T WOORK
sec10 = 0 ' was 10
DEC SEC ' increment tenths display
'sec10 = 9
IF SEC = 10 THEN
DEC MM01
SEC = 5

' increment seconds digit
IF MM01 = 10 THEN
MM01 = 0 ' was 10
DEC MM02 ' increment tens digit
IF MM02 = 10 THEN 'maximum time
' MM01 = 6
'DEC MM03 ' increment tens digit
' IF MM03 = 0 THEN 'maximum time
ops = M_STOP ' stops timer
' ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF


Next_Digit: ' Defines which LED is being cycled
INC digPntr ' point to next digit
IF digPntr = NumDigits Then ' check pointer --- number of LED (5), then resets DigPntr
digPntr = 0 ' wrap if needed
ENDIF

Update_Seqs: ' one display updated at a time
Segments = %00000000 ' clears the LED for next digit creates a crisper display.
READ Dig_Map + digPntr, DigCtrl ' RB this will shut off all LED' update digital control - DP_Map is a table with one value READ COMMAND gets data from table offsets it digPntr and puts it in DigCtrl
Segments = display(digPntr) ' RC this will shut off all LED ' output new segments - Controls the cathode

Check_Finish:
IF AtFinish = Yes THEN ' CHECKS TO SEE IF OPTO-TRANSISTOR IS BLOCKED; NO = 1 At_Finish = _PARMA1 = RB.0
ops = M_STOP ' MUST PUSH THE CLEAR BUTTON TO RESET: M_STOP = 2
ENDIF

IF Go = Yes THEN ' go button pressed
IF ops = M_CLEAR THEN ' were we cleared
ops = M_RUN ' yep so we can run
ENDIF
ENDIF
IF Clear = Yes THEN ' clear button pressed
IF ops = M_STOP THEN
PUT @ms, 0, 5, 9, 5, 0 'was 00000
ops = M_CLEAR ' clear the clock
ENDIF
ENDIF

RETURNINT ' reset the RTCC value and re-enables interrupts
' End interrupt routine start program code
' Clear and Start go directly to Ra.0 and Ra.1. Ra.1 going high starts the timer, but the timer must be in mode zero defined as RAO_CLEAR.
' The timer starts by updating ops to M-Run. The timer stops when the opto-transistor goes high causing the comparator to go high the timer
' will be stop by changing the ops mode to M_STOP

UPDATE_DISPLAY: ' called only once Read (Table + location) not an addtion, Variable or word so display should be Rc
' this will shut off individual LED
READ Seg_Map + sec10, display(0) ' display (0) is the LED for milliseconds
'IF sec10 = 0 THEN
'GOTO SKIPPER
'ELSE
READ Seg_Map + SEC, display(1) ' Transfers seg_Map data table into display array.
'ENDIF
'SKIPPER:
'IF SEC = 0 THEN
'GOTO SKIPPER2
'ELSE
READ DP_Map + MM01, display(2) 'was Seg_Map '
'ENDIF
'SKIPPER2:
'IF MM01 = 0 THEN
'GOTO SKIPPER3
'ELSE
READ Seg_Map + MM02, display(3) 'was DP_Map ' SETS THE LED COMPONENT WITH DP LIT.
'ENDIF
'IF MM02 = 0 THEN
'GOTO SKIPPER3
'ELSE
IF MM03 = 0 THEN
display(4) = %00000000 ' Blanks ms display
ELSE
READ Seg_Map + MM03, display(4)
ENDIF
'ENDIF
'SKIPPER3:
RETURN

'====================================================================================
' Data tables
'====================================================================================

Seg_Map: ' segments maps without DP
' .gfedcba
DATA %00111111 ' 0
DATA %00000110 ' 1
DATA %01011011 ' 2
DATA %01001111 ' 3
DATA %01100110 ' 4

DATA %01101101 ' 5
DATA %01111101 ' 6
DATA %00000111 ' 7
DATA %01111111 ' 8
DATA %01100111 ' 9

'DATA %01110111 ' A
'DATA %01111100 ' B
'DATA %00111001 ' C
'DATA %01011110 ' D
'DATA %01111001 ' E
'DATA %01110001 ' F

DP_Map: ' segments maps with DP
sets the cathode
' .gfedcba
DATA %10111111 '0. data table for display 3 only
DATA %10000110 '1.
DATA %11011011 '2.
DATA %11001111 '3.
DATA %11100110 '4.

DATA %11101101 '5.
DATA %11111101 '6.
DATA %10000111 '7.
DATA %11111111 '8.
DATA %11100111 '9.

Dig_Map: ' Digit select map
'RB-76543210 millisec = RB3
DATA %11110000 '240
DATA %11101000 '232
DATA %11011000 '216
DATA %10111000 '184
DATA %01111000 '120

Comments

  • JonnyMacJonnyMac Posts: 9,216
    edited 2008-02-25 07:12
    There's a timer program in the SX/B help file that should be, well... helpful.
  • Wissam Ch.Wissam Ch. Posts: 36
    edited 2008-02-25 14:07
    Hello Brandit ,
    I was working two days ago on a project that had a count down procedure .

    Here is part of the code i used to solve the issue you are facing.
    The point here is to monitor the roll of the byte variable from 00 to FF .


    ; #########
    some pre code goes here....

    DEC Sec ; Decrement seconds
    MOV W,#$FF
    MOV W,Sec - W ; check if register moved from 00 to FF
    MOV W,#09
    SNZ
    MOV Sec,W ; reset seconds to 9
    SNZ
    DEC Sec10 ; Decrement 10th of seconds
    MOV W,#$FF
    MOV W,Sec10 - W ; check if register moved from 00 to FF
    MOV W,#05
    SNZ
    MOV Sec10,W ; reset 10th seconds to 5
    ##########################

    Hope this could help .
  • BanditBandit Posts: 12
    edited 2008-03-02 21:50
    Thanks Wissam

    Your code may guide me in the right direction.http://forums.parallax.com/forums/emoticons/roll.gif
    roll
Sign In or Register to comment.