Count up/down timer
This is a complete project Jure sent me with PCB design. It can be compiled
with the BASCOM-8051 info since Jure used the AT89C2051 with 2KB of code.
Here is the comment from Jure:
Here is the description of the Timer:
S.E. Timer can countdown from 1-99 seconds, 1-99 minutes or 1-99 hours.
Timer has 4+1 press buttons, UP, DOWN, MODE, START + RESET
UP, DOWN set time that we want to count down, MODE selects the unit (sec.,
min. or hours) that we want to count down. Once we set time and set MODE, we can
start countdown sequence. After countdown the relay turns on. To restart Timer,
we must press RESET button.
In the countdown mode no buttons except RESET are active.
Download source code in .BAS file Download PCB file #1 Download PCB file #2
And here is the BASCOM-8051 code:
' S.E. Timer, improved version
' author Jure
Mikeln, December 2000
' S.E. Timer can
countdown from 1-99 seconds
' 1-99 minutes
or 1-99 hours
' Timer has
4+1 press buttons, UP, DOWN, MODE, START + RESET
' UP, DOWN set
time that we want to count down
' MODE selects
the unit (sec., min. or hours) that we want to
' count down.
Once we set time, set MODE, we can start countdown
' sequence.
After countdown the relay turns on. To restart Timer,
' we must
press RESET button.
' In the
countdown mode no buttons except RESET are active.
' PCBs for
Timer are available from: stik@svet-el.si
' or
www.svet-el.si/english
Dim Clock As Byte , Stevec As Byte , Segmenti As Byte , X As Byte , P15 As Bit , P16 As Bit , P17 As Bit
Dim Clock12 As Word , Stevec1 As Bit , Stevec2 As Byte , Mux As Byte , Prikaz As Bit
Dim T1 As Bit , T2 As Bit , T3 As Bit
Dim Clock1 As Byte , Mod1 As Byte
Dim Izracun As Bit , Pomozna_v As Byte , Enice As Byte , Desetice As Byte , Minute As Word , Ure As Word
' SEGMENTS ARE AT P1.1 to P1.7
' P1.6 flashes with respect Timer MODE
' Mod=1=>sec =>P1.6 flashes quickly, Mod=2=>min
=>P1.6 flashes slowly,
' Mod=3=>ure =>P1.6 glows constantly
Config Timer0 = Timer , Gate = Internal , Mode = 2
Config Debounce = 10
'Gate = Internal
'Mode = 2 8 bit auto reaload
Enable Interrupts
Enable Timer0
Load Timer0 , 250
Start Timer0
'initial settings
Clock = 0
Stevec = 0
T1 = P3.0 ' UP button
T2 = P3.2 ' DOWN button
T3 = P3.1 ' MODE button
'P3.0 and P3.1 together ' START button, see schematics
P16 = 1
P15 = 0
Mod1 = 1
P3.7 = 0
Reset Segmenti
Minute = 0
Clock12 = 0
Ure = 0
On Timer0 Timer_0_int
'------------------------------------------------------------------
'Main program
Do
T3 = P3.1
T1 = P3.0
T2 = P3.2
If Mod1 = 1 Then
P1.6 = P15
End If 'P1.6
flashes quickly (seconds)
If Mod1 = 2 Then
P1.6 = P16 'P1.6 flashes
slowly (minutes)
End If
If Mod1 = 3 Then
P1.6 = 0 'P1.6 glows
constantly (hours)
End If
Gosub Tipke
Gosub Izracun1
Loop
End
'------------------------------------------------------------------
'Interrupt routine
Timer_0_int:
Incr Clock12
If Clock12 > 4000 Then
Clock12 = 0
P16 = Not P16 'one second pulse
P17 = Not P17 'seconds indication
End If
Incr Clock
If Clock > 19 Then 'each 5 mS change
of MUX-a
Clock = 0
Incr Mux
If Mux > 3 Then
Mux = 0
End If
Prikaz = 1
Incr Clock1
If Clock1 > 29 Then
Clock1 = 0
P15 = Not P15 'LED flashes
every 150mSec.
End If
End If
Return
'------------------------------------------------------------------
'Press buttons routine
Tipke:
If Mux > 2 Then 'this prevents
turning LED display off when buttons are pressed
Debounce T1 , 0 , Stevec1 , Sub 'UP
Debounce T2 , 0 , Stevec , Sub 'DOWN
Debounce T3 , 0 , Mod , Sub 'MODE
End If
Return
'------------------------------------------------------------------
'Decrement variable Stevec
Stevec:
If Stevec > 0 Then
Decr Stevec
If Stevec = 255 Then
Stevec = 99
End If
End If
Return
'------------------------------------------------------------------
'Increment variable Stevec
Stevec1:
If T3 = 0 Then 'start countdown
Gosub Odstej1 'go to sub for decrementing
Return
End If
Incr Stevec
If Stevec > 99 Then 'prevent Stevec to increment over 99
Stevec = 0
End If
Return
'------------------------------------------------------------------
'MODE select routine
'Mod1=1 seconds, Mod1=2 minutes, Mod1=3 hours
Mod:
Incr Mod1
If Mod1 > 3 Then
Mod1 = 1
End If
Return
'------------------------------------------------------------------
'Routine that calculates tenths & units
Izracun1:
Desetice = Stevec / 10
Pomozna_v = Desetice * 10
Enice = Stevec - Pomozna_v
If Prikaz = 1 Then
Prikaz = 0
P3.4 = 1
P3.5 = 1 'disable display
'disable display
If Mux = 0 Then
Pomozna_v = Enice 'show units
Gosub Prikaz1 'gosub for displaying
P3.5 = 0 'enable
transistor for units
End If
If Mux = 1 Then
Pomozna_v = Desetice 'show tenths
Gosub Prikaz1 'gosub for displaying
P3.4 = 0 'enable
transistor for tenths
End If
End If
Return
'------------------------------------------------------------------
'Displaying routine
Prikaz1:
Restore Tabela
For X = 0 To 9
Read Segmenti
If X = Pomozna_v Then 'if X = value to display
P1 = Segmenti 'then set this value to Port1
Exit For 'and exit FOR
loop
End If
Next
Return
'---- data for LED display ------
Tabela:
Data 96 , 249 , 196 , 208 , 89 , 82 , 66 , 248 , 64 , 80
'------------------------------------------------------------------
'Routine that decrements preset time
Odstej1:
Clock12 = 0 'reset timer
variable
P16 = 1
Do
If Stevec > 0 Then 'condition that prevents decr. below zero
Gosub Ure_sub 'gosub hours
Gosub Minute_sub 'gosub minutes
Gosub Sekunde_sub 'gosub seconds
Else
Exit Do 'it does not
decrement if Stevec=0
End If
Loop
Return
'------------------------------------------------------------------
'Routine for minutes decrement
Minute_sub:
If Mod1 = 2 Then 'check if Timer
is in minutes MODE
Do
P1.6 = P17 'signalization
that it's minutes
Min1:
If P16 = 0 Then 'wait until P16 changes it's state (every second)
P16 = Not P16
Incr Minute 'incr Minutes variable
If Minute > 59 Then 'if minutes > 59 then
Minute = 0
Decr Stevec 'decr variable
Stevec every 60 sec
If Stevec = 1 Then
Stevec = 60
Mod1 = 1
Return
End If
If Stevec = 0 Then
P3.7 = 1 'turn on relay
P3.4 = 0 'both displays
are on
P3.5 = 0
P1 = 96 'display "0" on display
Stop
End If
End If
End If
Gosub Izracun1 'display value of Stevec variable
Loop
End If
Return
'------------------------------------------------------------------
'Routine that decrements preset hours
Ure_sub:
If Mod1 = 3 Then 'check if Timer
is in hours MODE
Do
P1.6 = 0 'signalization of
Hours MODE
If P16 = 0 Then 'wait until P16 changes it's state (every second)
P16 = Not P16
Incr Ure
If Ure > 3599 Then
Ure = 0
Decr Stevec 'decrement Stevec
variable every 3600 seconds
If Stevec = 1 Then 'when Stevec=1,
Stevec = 60 'Set Stevec=60 and decrement minutes
Mod1 = 2 'Set Mod1 to minutes MODE
Return
End If
If Stevec = 0 Then
P3.7 = 1 'turn on relay
P3.4 = 0 'both displays
are on
P3.5 = 0
P1 = 96 'display number "0"
Stop
End If
End If
End If
Gosub Izracun1 'display value of Stevec variable
Loop
End If
Return
'------------------------------------------------------------------
'Routine for Seconds decrementing
Sekunde_sub:
Do
If Mod1 = 1 Then
If P16 = 0 Then 'wait until P16 changes it's state (every second)
P16 = Not P16
Decr Stevec 'Decrement variable Stevec for 1
If Stevec = 0 Then
P3.7 = 1 'turn on relay
P3.4 = 0 'both displays
are on
P3.5 = 0
P1 = 96 'display number "0"
Stop
End If
End If
End If
Gosub Izracun1 ''display value
of Stevec variable
Loop
Return
'------------------------------------------------------------------
|