'       S.E. Timer, izboljsana verzija s Tiny2313 in 4 displeji
'       avtor Jure Mikeln, Jan 2008
'       S.E. Timerju lahko nastavljamo cas od 1-9999 sekund in 1-9999 minut
'       na koncu je Powerdown, ki zmanjsa porabo na nekaj ľA
'       verzija, ki vklopi rele, ko timer starta in ga izklopi, ko timer odsteje.
'       ko nastavljamo stetje po pritisku UP pricne stevec steti hitreje, pri tipki DOWN odsteva samo po eno


$regfile = "attiny2313.DAT"

Dim Clock As Byte , Stevec As Word , Segmenti As Byte , X As Byte , P15 As Bit , P16 As Bit , P17 As Bit
Dim Clock12 As Word , Mux As Byte , Prikaz As Bit
'Dim T1 As Bit , T2 As Bit , T3 As Bit
Dim Clock1 As Byte , Mod1 As Bit
Dim Pomozna_v As Word , Enice As Byte , Desetice As Byte , Minute As Word , Pomozna_v3 As Word
Dim Stotice As Word , Tisocice As Word , Pomozna_v2 As Word

Dim Test1 As Byte , Test2 As Byte , Test3 As Word , Test4 As Word
Test4 = 4000
Test1 = 10
Test2 = 0



' SEGMENTI SO NA Pb.1 DO Pb.7
' Pb.6 utripa glede na to, v kaksnem rezimu delovanja je Timer
' Mod=1=>sek =>Pb.6 hitro utripa, Mod=2=>min =>Pb.6 pocasi utripa,
Config Timer0 = Timer , Prescale = 1
Config Debounce = 10
On Ovf0 Tim0_isr
Config Timer0 = Timer , Prescale = 1
Enable Timer0                                               ' enable the timer interrupt
Enable Interrupts                                           'allow interrupts to occur
Start Timer0

'rele izhod na Pd.6


Portd = &B01111100
Ddrd = &B01111100

Portb = &B00000000
Ddrb = &B11111111


'zacetne nastavitve

Clock = 0
'PD.0 in PD.1 skupaj  ' START tipka
P16 = 1
P15 = 0
Mod1 = 0                                                    'MODE = sekunde

Ddrd.1 = 0                                                  'vhod
If Pind.1 = 0 Then                                          'ce ob Resetu pritisnemo tipko UP
   Mod1 = 1                                                 'nastavimo MODE = minute
End If                                                      'sicer MODE = sekunde
Ddrd.1 = 1


Portd.6 = 0                                                 'rele izhod na Pd.6

Reset Segmenti
Minute = 0
Clock12 = 0



'------------------------------------------------------------------
'Glavni program

Do

If Mod1 = 0 Then
   Portb.0 = P15                                            'signalizacija sekund, hitro utripanje DP
Else
   Portb.0 = P17                                            ' signalizacija MINUT, pocasno utripanje na DP
End If

Gosub Tipke
Gosub Izracun1

Loop
End
'------------------------------------------------------------------
'Prekinitvena rutine


'------------------------------------------------------------------

Tim0_isr:
Incr Clock12
If Clock12 > 46874 Then
   Clock12 = 0
   P16 = Not P16                                            'sekundni impulz
   P17 = Not P16                                            'pomozna indikacija sekund
End If

   If Pind.1 = 0 And Pind.0 = 1 Then                        'da normalno starta odstevanje
   Incr Test3
   If Test3 > Test4 Then
      Test3 = 0
      Incr Stevec
      Incr Test2
      If Test2 > 4 Then                                     'po 5 sekundah se pricne hitro stetje
         Test4 = 1000                                       'cas 125 ms
         Else
         Test4 = 8000                                       'cas 1 sekunde
      End If
   End If
   End If

Incr Clock
If Clock > 190 Then                                         'vsakih 5 mS je sprememba MUX-a
   Clock = 0
   Incr Mux
   If Mux > 3 Then
      Mux = 0
   End If
   Prikaz = 1
   Incr Clock1
   If Clock1 > 23 Then
      Clock1 = 0
      P15 = Not P15                                         ' hitro utripanje LED-ice 150mS
   End If
End If
Return
'------------------------------------------------------------------
'Rutina, ki ugotavlja stanje tipk

Tipke:

Ddrd.0 = 1                                                  'vhod
Ddrd.1 = 1                                                  'vhod
Portd.0 = 1
Portd.1 = 1

Debounce Pind.1 , 0 , Stevec1 , Sub                         'UP
Debounce Pind.0 , 0 , Stevec , Sub                          'DOWN
Portd.0 = 1
Portd.1 = 1


Return
'------------------------------------------------------------------
'Rutina za manjsanje spremenljivke Stevec

Stevec:
'If Stevec > 0 Then
    Decr Stevec
'   Test2 = 0                  'resetiramo pomozno spremenljivko
'   Test3 = 0                  'resetiramo pomozno spremenljivko

   If Stevec = 65535 Then
      Stevec = 0
   End If
'End If

Return
'------------------------------------------------------------------
'Rutina za vecanje spremenljivke Stevec

Stevec1:
If Stevec = 0 Then
Return
Else                                                        'tipka je definitivno pritisnjena
If Pind.0 = 0 Then                                          'start odstevanja
'   Pisk = 1                   'znak za zac. odstevanja
   Gosub Odstej1                                            'gre na odstevanje
   Return                                                   'se vrne iz subrutine
End If

Incr Stevec
Test2 = 0                                                   'resetiramo pomozno spremenljivko
Test3 = 0                                                   'resetiramo pomozno spremenljivko


If Stevec > 9999 Then
   Stevec = 9999
End If
End If
Return
'------------------------------------------------------------------
'Rutina za izracun desetic in enic

Izracun1:
   Tisocice = Stevec / 1000                                 'tisocica
   Pomozna_v = Tisocice * 1000                              'pomozna za izracun stotic

   Pomozna_v3 = Stevec - Pomozna_v

   Stotice = Pomozna_v3 / 100
   Pomozna_v2 = Stotice * 100

   Pomozna_v = Pomozna_v3 - Pomozna_v2

   Desetice = Pomozna_v / 10
   Pomozna_v3 = Desetice * 10
   Enice = Pomozna_v - Pomozna_v3




If Prikaz = 1 Then
   Prikaz = 0
   Portd.4 = 1                                              'displej 2
   Portd.5 = 1                                              'displej 1
   Portd.3 = 1                                              'displej 3
   Portd.2 = 1                                              'displej 4


   If Mux = 0 Then
      Pomozna_v = Enice                                     'enice
      Ddrb.0 = 0
      Portb.0 = 1                                           'DP ni vklopljen
      Gosub Prikaz1

      Portd.5 = 0                                           'displej 1, enice
      If Mod1 = 0 Then
         Ddrb.0 = 1
      End If
   End If

   If Mux = 1 Then
      Pomozna_v = Desetice                                  ' desetice
      Portb.0 = 1                                           'DP ni vklopljen
      Ddrb.0 = 0
      Gosub Prikaz1

      Portd.4 = 0                                           'displej 2 desetice
      If Mod1 = 1 Then
         Ddrb.0 = 1
      End If
   End If

   If Mux = 2 Then
      Pomozna_v = Stotice                                   ' desetice
      Ddrb.0 = 0
      Portb.0 = 1                                           'DP ni vklopljen
'      Ddrb.0 = 1              'prikaz DP
      Gosub Prikaz1

      Portd.3 = 0                                           'displej 3   stotice
'      If Mod1 = 1 Then
'         Ddrb.0 = 1
'      End If
   End If

   If Mux = 3 Then
      Pomozna_v = Tisocice                                  ' desetice
      Ddrb.0 = 0
      Portb.0 = 1                                           'DP ni vklopljen
      Gosub Prikaz1

      Portd.2 = 0                                           'displej 4 tisocice
'      If Mod1 = 1 Then
'         Ddrb.0 = 1
'      End If
   End If

End If
Return
'------------------------------------------------------------------
'Rutina za prikaz podatkov

Prikaz1:                                                    ' rutina za prikaz na LED displeju

Restore Tabela


   For X = 0 To 9
    Read Segmenti
    If X = Pomozna_v Then                                   'ce je X = vrednosti, ki jo je treba izpisati
       Portb = Segmenti                                     'postavi vrednost prebrane tabele na Port1
       Exit For                                             'in konca FOR zanko
    End If
   Next
Return

'---- podatki za izpis na LED displeju ------
Tabela:
Data 16 , 125 , 35 , 41 , 77 , 137 , 129 , 61 , 1 , 9
''

'Rutina za odstevanje nastavljenega casa

Odstej1:
Clock12 = 0                                                 'reset spremenljivke v timerju
Portd.6 = 1                                                 'vklop releja
P16 = 1

Do

' ce je stevec>1 in ce niso sekunde

If Stevec > 0 Then                                          'pogoj, da ne odsteva v "minus 0"
   Gosub Minute_sub
   Gosub Sekunde_sub
   Else
   Exit Do                                                  'ne steje, ce je Stevec=0
End If
Loop
Return
'------------------------------------------------------------------
'Rutina za odstevanje minut

Minute_sub:

If Mod1 = 1 Then                                            'preveri, ali so nastavljene minute
   Do

If Mod1 = 0 Then
   Portb.0 = P15                                            'signalizacija sekund, hitro utripanje DP
Else
   Portb.0 = P17                                            ' signalizacija MINUT, pocasno utripanje na DP
End If

   Min1:
     If P16 = 0 Then                                        'ce so, potem pocaka na spremembo
        P16 = Not P16
        Incr Minute
        If Minute > 59 Then
           Minute = 0
           Decr Stevec                                      'odsteva stevec vsakih 60 sek
           If Stevec = 1 Then
              Stevec = 60
              Mod1 = 0
              Return                                        'gre nazaj
           End If
        End If
     End If
     Gosub Izracun1                                         'izpise stanje Stevca
     Loop
End If
Return
'------------------------------------------------------------------
'Rutina za odstevanje sekund

Sekunde_sub:
Do

If Mod1 = 0 Then
   If P16 = 0 Then                                          'vsako sekundo
      P16 = Not P16
      Decr Stevec                                           'Odsteje Stevec Za 1
      If Stevec = 0 Then
         Portd.6 = 0                                        'Izhod je 0 in vklopi rele
         Portd.4 = 0                                        'vsi displeji vklopljeni
         Portd.5 = 0
         Portd.3 = 0                                        '
         Portd.2 = 0

         Portb = 16                                         'prikaz stevilke "0"
              Wait 2
              Portb = 255
              Portd = 255
              Portd.6 = 0                                   'Izhod je 0 in izklopi rele
              Powerdown
              Stop
      End If
   End If
End If
Gosub Izracun1                                              'izpise stanje Stevca
Loop
Return
'------------------------------------------------------------------