'-----------------------------------------------------------------------------------------
'Titel                    : 1000erDezimalUhr
'Name                     : KiloDezimalUhr
'Datei                    : KiloDezimalUhr.bas
'Autor                    : Arno Schweißinger
'Datum                    : 28.10.2012
'Version                  : 0.02
'Compiler                 : Bascom 1.11.8.7
'MicroController          : 1x AtMega8 1MHz interner Takt
'Hardware                 : 1x Uhrenquarz 32768Hz an TOSC1/2 - Pin 9/10
'                           3x MOS 4094
'                           3x 7Segmentanaeige
'
'                           Pind.0 an Data   alle MOS 4094
'                           Pind.1 an Clock  alle MOS 4094
'                           Pind.2 an Strobe1 IC1 MOS 4094
'                           Pind.3 an Strobe2 IC2 MOS 4094
'                           Pind.4 an Strobe3 IC3 MOS 4094
'
'                           Pinb.1 Lsp für Stundensignal
'                           Taster1 Alias Portd.6  Minuten
'                           Taster2 Alias Portd.7  Stunden
'
'
'
'Stromversorgung:         : 5V ,
'Besonderes               :
'Letzte Änderung          :V0.01: 29.10.2012
'                          V0.02: 01.11.2012  Routine Sub Ausgabe_stellen
'
'-----------------------------------------------------------------------------------------

$regfile = "m8def.dat"
$crystal = 1000000

'Config Portd = Output
Ddrd = &B00111111                                           ' Pin PD6 PD7 auf Eingang
Portd = &B1100000                                           ' Pin PD6 PD7 Pullup aktivieren
Dat Alias Portd.0                                           ' Datenübertragung an MOS4094
Cl Alias Portd.1                                            ' Clock  Signal an MOS4094
Strobe1 Alias Portd.2                                       ' Strobe Signal U1 MOS4094
Strobe2 Alias Portd.3                                       ' Strobe Signal U2 MOS4094
Strobe3 Alias Portd.4                                       ' Strobe Signal U3 MOS4094


Taster1 Alias Pind.6                                        ' Minuten
Taster2 Alias Pind.7                                        ' Stunden
Soundpin Alias Pinb.1

'configure clock
Config Date = Dmy , Separator = .                           ' ANSI-Format
Config Clock = Soft                                         ' this is how simple it is
Enable Interrupts


Declare Sub Init_prog
Declare Sub Tastatur
Declare Sub Sende4094
Declare Sub Loeschen4094
Declare Sub Stundensignal
Declare Sub Korrektur
Declare Sub Ausgabe
Declare Sub Ausgabe_stellen
Declare Sub Zahlout
Declare Sub Dezimalzeit

Const Starttime = "10:35:00"
Const Zeitkorrektur = 0                                     ' plus/minus x Sekunden am Tag, Max 30 Sek je Tag

Dim Segmente(3) As Byte                                     ' 3 * 8bit für LED, gesendet an 4093
Dim Old_sec As Byte                                         ' Hauptprogramm
Dim I As Byte                                               ' Registerloeschen; Uebertragen;  Zählschleifen
Dim J As Byte                                               ' Registerloeschen; Uebertragen
Dim Korrekturflag As Byte                                   ' Sub Korrektur  einmal am Tag korrigieren
Dim Sekunden As Long                                        ' Sub Dezimalzeit
Dim Cache As Long                                           ' Sub Dezimalzeit
Dim Temp As Byte                                            ' Zwischenspeicher


'-------------------------
'      Hauptprogramm
'-------------------------
'Begin
Call Init_prog
  Do
   If _sec <> Old_sec Then                                  ' Sekundentakt
      Old_sec = _sec
      Call Dezimalzeit
      Call Ausgabe
      Call Stundensignal
      Call Tastatur                                         ' Taster auslesen
      Call Korrektur                                        ' wird einmal am Tag ausgeführt
   End If
  Loop
End                                                         ' ende Hauptprogramm

'-----------------------------------------------------------------------------------------
Sub Init_prog
  Segmente(1) = Lookup(, Balken)                          ' Balken in der Mitte -Seg7
  Segmente(2) = Lookup(, Balken)                          ' Balken in der Mitte -Seg7
  Segmente(3) = Lookup(, Balken)                          ' Balken in der Mitte -Seg7
  Call Sende4094
  Sound Soundpin , 40 , 40                                  ' Bestätigungston
  Waitms 100                                                ' warte kurz
  Sound Soundpin , 40 , 40                                  ' Bestätigungston
  Time= Starttime
End Sub


'-----------------------------------------------------------------------------------------
Sub Dezimalzeit
   Sekunden = Secofday()                                    ' Vergangene Sekunden des Tages
  ' Umrechnen ins Dezimalsystem
   Sekunden = Sekunden * 625                                ' Dezimaltag hat 100*100*100 Sekunden 10000=2*2*2*2          *5*5*5*5
   '625 = 5*5*5*5
   Sekunden = Sekunden / 54                                 ' ein Tag hat 86400 Sekunden            864=2*2*2*2  *2*3*3*3
    '54 = 2*3*3*3
   Cache = Sekunden / 100000
   Segmente(3) = Cache                                      ' 100er
   Cache = Cache * 100000
   Sekunden = Sekunden - Cache

   Cache = Sekunden / 10000
   Segmente(2) = Cache                                      ' 10er
   Cache = Cache * 10000
   Sekunden = Sekunden - Cache

   Cache = Sekunden / 1000
   Segmente(1) = Cache                                      ' 1er
End Sub


'-----------------------------------------------------------------------------------------
Sub Ausgabe
    Segmente(1) = Lookup(segmente(1) , Zahlen)              ' Zahl in Segmente wandeln     0-9
    Segmente(1).= _sec.0                                  ' Dezimalpunkt blinkt im Sekundertakt
    Segmente(2) = Lookup(segmente(2) , Zahlen)
    Segmente(3) = Lookup(segmente(3) , Zahlen)
    Call Sende4094                                          ' Bits an Latch MOS4094 senden
End Sub


'-----------------------------------------------------------------------------------------
Sub Ausgabe_stellen
    Sound Soundpin , 10 , 20                                ' Bestätigungston
    Segmente(2) = Temp / 10                                 ' Zehener Stellen
    Segmente(1) = Temp Mod 10                               ' Einer Stellen
    Segmente(1) = Lookup(segmente(1) , Zahlen)              ' Zahl in Segmente wandeln     0-9
    Segmente(2) = Lookup(segmente(2) , Zahlen)
    Segmente(3) = Lookup(, Balken)
    Call Sende4094                                          ' Bits an Latch MOS4094 senden
    Waitms 500
End Sub


'-----------------------------------------------------------------------------------------
Sub Tastatur
'------------------ Minuten stellen ------------------------
If Taster1 = 0 Then
  _sec = 00                                                 ' Sekunden löschen
  _min = _min + 1
  If _min = 60 Then _min = 0
  Temp = _min
  Call Ausgabe_stellen
  Waitms 500                                                ' 1/2 Sekunde warten
  While Taster1 = 0                                         ' Taster gehalten, dann scheller Vorlauf
    _min = _min + 1
    If _min = 60 Then _min = 0
    Temp = _min
    Call Ausgabe_stellen
  Wend
End If
'------------------ Stunden stellen ------------------------
If Taster2 = 0 Then
  _hour = _hour + 1
  If _hour = 24 Then _hour = 0
  Temp = _hour
  Call Ausgabe_stellen
  Waitms 500                                                ' 1/2 Sekunde warten
  While Taster2 = 0                                         ' scheller Vorlauf
    _hour = _hour + 1
    If _hour = 24 Then _hour = 0
    Temp = _hour
    Call Ausgabe_stellen
  Wend
End If
End Sub


'-----------------------------------------------------------------------------------------
Sub Loeschen4094                                            ' MOS 4093
  For J = 2 To 4                                            ' Portd.2 bis Portd.4
    For I = 0 To 7
      Reset Dat                                             ' der Übersicht wegen,  einmal low immer low
      Set Cl
      Waitus 10                                             ' Clocksignal am 4093 erzeugen
      Reset Cl
    Next I
    Set Portd.j
    Waitus 100                                              ' 4093 Ausgänge setzen
    Reset Portd.j                                           ' kein strobe senden!!!!! LEDs flackern sonst
  Next J
End Sub


'-----------------------------------------------------------------------------------------
Sub Sende4094
  For J = 2 To 4                                            ' Portd.2 bis Portd.4
    For I = 7 To 0 Step -1
      Dat = Segmente(- 1).i
      Set Cl
      Waitus 10
      Reset Cl                                              ' Clocksignal am 4093 erzeugen
    Next I
    Set Portd.j
    Waitus 100                                              ' 4093 Ausgänge setzen
    Reset Portd.j
  Next J
End Sub


'-----------------------------------------------------------------------------------------
Sub Korrektur                                               ' Zeit Korrektur einmal am Tag, wenn der Quarz etwas abweicht
  If Korrekturflag = 0 Then                                 ' Korrekturbit setzen
    If _sec = 0 Then
     If _min = 0 Then
       If _hour = 23 Then
        Korrekturflag = 1
       End If
     End If
    End If
  End If

  If Korrekturflag = 1 Then                                 ' Korrektur vornehmen
    If _sec = 30 Then
     If _min = 30 Then                                      ' es ist wo weit
       If _hour = 23 Then
        _sec = _sec + Zeitkorrektur
        Korrekturflag = 0
       End If
     End If
    End If
  End If
End Sub


'-----------------------------------------------------------------------------------------
Sub Stundensignal
  If _sec = 0 Then
     If _min = 0 Then
       If _hour > 6 Then                                    ' nachts nicht Pipsen
         If _hour < 23 Then
           Sound Soundpin , 20 , 40
           Sound Soundpin , 40 , 40
         End If
       End If
     End If
  End If
End Sub


'-----------------------------------------------------------------------------------------
Zahlen:
'Segm   gfe_dcba
Data &B0011_1111                                            ' 0
Data &B0000_0110                                            ' 1
Data &B0101_1011                                            ' 2
Data &B0100_1111                                            ' 3
Data &B0110_0110                                            ' 4
Data &B0110_1101                                            ' 5
Data &B0111_1101                                            ' 6
Data &B0000_0111                                            ' 7
Data &B0111_1111                                            ' 8
Data &B0110_1111                                            ' 9
Data &B0110_0111                                            ' A
Data &B0111_1100                                            ' B
Data &B0011_1001                                            ' C
Data &B0101_1110                                            ' D
Data &B0111_1001                                            ' E
Data &B0111_0001                                            ' F


Balken:
Data &B00000000                                             ' 0 alles aus
Data &B00000001                                             ' 1 Seg  1
Data &B00000010                                             ' 2 Seg  2
Data &B00000100                                             ' 3 Seg  3
Data &B00001000                                             ' 4 Seg  4
Data &B00010000                                             ' 5 Seg  5
Data &B00100000                                             ' 6 Seg  6
Data &B01000000                                             ' 7 Seg  7
Data &B10000000                                             ' 8 DezPunkt