'Nixie-Uhr für Atmega 328 mit zwei Ziffern Version 1.0
'Basierend auf Nixie_DCF77_Mega644P_2x16LCD_V_3.2.bas
'

$regfile = "m328pdef.dat"
$crystal = 10000000

$hwstack = 128
$swstack = 128
$framesize = 128

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.3 , Db6 = Portd.2 , Db7 = Portd.1 , E = Portd.0 , Rs = Portc.5
Config Lcdbus = 4
'Ports für Einser-Werte als Ausgang deklarieren
Config Portb.4 = Output
Config Portb.2 = Output
Config Portb.1 = Output
Config Portb.3 = Output
'Ports für Zehner-Werte als Ausgang deklarieren
Config Portc.3 = Output
Config Portc.1 = Output
Config Portc.0 = Output
Config Portc.2 = Output

Enable Interrupts
Config Date = Dmy , Separator = .


Config Dcf77 = Pind.5 , Timer = 1 , Timer1sec = 1 , Debug = 1 , Inverted = 1 , Check = 0


Dim I As Integer
Dim Sec_old As Byte , Dcfsec_old As Byte
Dim Pulspause As Byte
Dim Sekunde As Byte
Dim Sekunde_str As String * 3
Dim Sommerwinter As String * 6
Dim Temp As Byte
Dim Dcftemp As String * 6
Dim Dcfflag As Byte
Dim Sekunden As Byte , Sekundenl As Byte , Sekundenh As Byte , Sekundens As String * 1
Dim Stunden As Byte , Stundenl As Byte , Stundenh As Byte , Stundens As String * 1
Dim Minuten As Byte , Minutenl As Byte , Minutenh As Byte , Minutens As String * 1
Dim Minuten_alt As Byte
Dim Ziffer As Byte
Dim I1 As Byte , I2 As Byte
Dim Stundenalt As Byte
Dim Ee_betriebsstunden As Eram Long
Dim Betriebsstunden As Long
Dim Betriebszeit As String * 11
Dim Betriebstage As Long
Dim Betriebstage_s As String * 5
Dim Umschaltflag As Byte

'Symbol Uhr
Deflcdchar 1 , 14 , 17 , 21 , 21 , 23 , 17 , 14 , 32
'Symbol Puls
Deflcdchar 2 , 32 , 14 , 10 , 10 , 10 , 10 , 27 , 32


Umschaltflag = 0
Sec_old = 99 : Dcfsec_old = 99
Time$ = "67:89:45"
'##############
'Betriebsstunden holen
Betriebsstunden = Ee_betriebsstunden
'Beim ersten Start ist alles auf FF
'dann 1000h voreinstellen (In Betrieb seit 2.2.2016 = 1000h bis 1.4.16)
If Betriebsstunden < 0 Then
   Ee_betriebsstunden = 1000
   Betriebsstunden = 1000
End If
Betriebszeit = Str(betriebsstunden)
Betriebstage = Betriebsstunden / 24
'z.B. Betriebstage = 364..
Betriebstage = Betriebstage + 10000
'..Betriebstage sind dann 10364
Betriebstage_s = Str(betriebstage)
'Ausgabe Betriebstage
Minutens = Mid(betriebstage_s , 5 , 1)
Minuten = Val(minutens)
Minuten = Makebcd(minuten)
'Gosub Ausgabe_minuten_low

Minutens = Mid(betriebstage_s , 4 , 1)
Minuten = Val(minutens)
Minuten = Makebcd(minuten)
'Gosub Ausgabe_minuten_high

Stundens = Mid(betriebstage_s , 3 , 1)
Stunden = Val(stundens)
Stunden = Makebcd(stunden)
'Gosub Ausgabe_stunden_low

Stundens = Mid(betriebstage_s , 2 , 1)
Stunden = Val(stundens)
Stunden = Makebcd(stunden)
'Gosub Ausgabe_stunden_high
'############
Cursor Off
Cls
Locate 1 , 1
Lcd "f" ; Chr(245) ; "r Nade & Ralph"
Locate 2 , 1
Lcd Betriebszeit ; " h"
Wait 2
Locate 2 , 1
Lcd "Migele 10.06.16"
Wait 2

'Kathoden reinigen
'Gosub Cathode_poisoning_reduction
'Stundenzähler für ersten Start auf unmöglichen Wert setzen
Stundenalt = 255
'############################################################
'Hauptschleife
Do
   Umschaltflag = Umschaltflag + 1
   If Umschaltflag = 5 Then

      Umschaltflag = 1
   End If

'+++++++++++++++ DCF77 holen ++++++++++++++++++++++++++
   'Atomzeit holen
   For I = 1 To 78
       Waitms 10
       If Sec_old <> _sec Then
         Exit For
       End If
       If Dcfsec_old <> Dcf_sec Then
         Exit For
       End If
   Next

   Waitms 220
    Sec_old = _sec
    Dcfsec_old = Dcf_sec
   Temp = Dcf77timezone()
   If Temp = 2 Then
      Sommerwinter = "Sommer"
   End If
   If Temp = 1 Then
      Sommerwinter = "Winter"
   End If
'+++++++++++++++++++++ Ausgabe LCD ++++++++++++++++++++
   Locate 1 , 1
   Lcd Time$ ; Date$
   Locate 2 , 1
   Lcd Sommerwinter ;
   Locate 2 , 8
   Lcd Chr(2) ; Bin(dcf_bits)
 '+++++++++++++++++++ Reinigung Kathoden +++++++++++++++
   'immer um Mitternach die Kathoden reinigen (50 sek)
   If Time$ = "00:00:00" Then
      'Gosub Cathode_poisoning_reduction
   End If
 '+++++++++++ Ausgabe Ziffern ++++++++++++++++++++++++++
   'Ausgabe Minuten Low
   'time$=hh:mm:ss
   If Umschaltflag < 3 Then
      Portd.7 = 1
      Portb.0 = 0
      Minutens = Mid(time$ , 5 , 1)
      Minuten = Val(minutens)
      'Jede Minute eine Pflegerunde einlegen
      If Minuten <> Minuten_alt Then
         Minuten_alt = Minuten
         'Gosub Cathode_poison_redu_minute
      End If
      Minuten = Makebcd(minuten)
      Gosub Ausgabe_minuten_low
        'Ausgabe Minuten High
      'time$=hh:mm:ss
      Minutens = Mid(time$ , 4 , 1)
      Minuten = Val(minutens)
      Minuten = Makebcd(minuten)
      Gosub Ausgabe_minuten_high
   End If
   If Umschaltflag > 2 Then
      Portd.7 = 0
      Portb.0 = 1
      'Ausgabe Stunden High
      'time$=hh:mm:ss
      Stundens = Mid(time$ , 1 , 1)
      Stunden = Val(stundens)
      Stunden = Makebcd(stunden)
      Gosub Ausgabe_stunden_high

      'Ausgabe Stunden Low
      'time$=hh:mm:ss
      Stundens = Mid(time$ , 2 , 1)
      Stunden = Val(stundens)
      Stunden = Makebcd(stunden)
      'Jede Stunde im EEprom um eins hochzählen..
      '.. beim Start ist Stundenalt 0, dann aktuelle Stunden in Stundenalt
      If Stundenalt = 255 Then
         Stundenalt = Stunden
      End If
      '.. Prüfen, ob Stunde um ist, dann ++stunden ins Eeprom
      If Stunden <> Stundenalt Then
         Betriebsstunden = Ee_betriebsstunden
         Incr Betriebsstunden
         Ee_betriebsstunden = Betriebsstunden
         Stundenalt = Stunden
      End If
      Gosub Ausgabe_stunden_low
   End If
   If Umschaltflag = 3 Then
      'Gosub Dunkel
   End If
   'Prüft, ob Uhr mit Atomzeit synchron, dann blinken Glimmlampen
   Gosub Dcf77_synchron_status
Loop

'####################################################### Unterprogramme ###

Dcf77_synchron_status:
'Uhr ist synchron , wenn Dcf_status.7=1
   If Dcf_status.7 = 1 Then
   'Glimmlampen blinken
      'Toggle Portd.7
      'Toggle Portb.0
   End If
Return

'+++++++++++++++++++++++++++++++++++++++++
Ausgabe_minuten_low:
'Ausgabe der Einer
   Ziffer = Minuten And &B00000001
   Portb.4 = Ziffer
   Shift Minuten , Right , 1
   Ziffer = Minuten And &B00000001
   Portb.2 = Ziffer
   Shift Minuten , Right , 1
   Ziffer = Minuten And &B00000001
   Portb.1 = Ziffer
   Shift Minuten , Right , 1
   Ziffer = Minuten And &B00000001
   Portb.3 = Ziffer
   Shift Minuten , Right , 1
Return

Ausgabe_minuten_high:
'Ausgabe der Zehner
   Ziffer = Minuten And &B00000001
   Portc.3 = Ziffer
   Shift Minuten , Right , 1
   Ziffer = Minuten And &B00000001
   Portc.1 = Ziffer
   Shift Minuten , Right , 1
   Ziffer = Minuten And &B00000001
   Portc.0 = Ziffer
   Shift Minuten , Right , 1
   Ziffer = Minuten And &B00000001
   Portc.2 = Ziffer
   Shift Minuten , Right , 1
Return

'+++++++++++++++++++++++++++++++++++++++++
Ausgabe_stunden_high:
'Ausgabe der Zehner-Stunden
   Ziffer = Stunden And &B00000001
   Portc.3 = Ziffer
   Shift Stunden , Right , 1
   Ziffer = Stunden And &B00000001
   Portc.1 = Ziffer
   Shift Stunden , Right , 1
   Ziffer = Stunden And &B00000001
   Portc.0 = Ziffer
   Shift Stunden , Right , 1
   Ziffer = Stunden And &B00000001
   Portc.2 = Ziffer
Return
'+++++++++++++++++++++++++++++++++++++++++
Ausgabe_stunden_low:
'Ausgabe der Einer-Stunden
   Ziffer = Stunden And &B00000001
   Portb.4 = Ziffer
   Shift Stunden , Right , 1
   Ziffer = Stunden And &B00000001
   Portb.2 = Ziffer
   Shift Stunden , Right , 1
   Ziffer = Stunden And &B00000001
   Portb.1 = Ziffer
   Shift Stunden , Right , 1
   Ziffer = Stunden And &B00000001
   Portb.3 = Ziffer
Return
'+++++++++++++++++++++++++++++++++++++++++
Dunkel:
   '######################################
      Minuten = 15
      Gosub Ausgabe_minuten_low
      Minuten = 15
      Gosub Ausgabe_minuten_high
      Waitms 100
Return
End