DCF77 und RTC mit ATmega unter BASCOM

So, mal wieder diesen Thread an die Oberfläche gezertt....

Ich bastel zur Zeit an einer eierlegenden Wollmilchsau (wenigstens für mich), bestehend aus einer DCF77-Uhr (mit RTC-Unterstützung) mit Anzeige über LCD-Display (16*4, Zeile 1 und 2) und zusätzlich über TWI (Hardware) auch auf 7-Segment-Anzeigen, sowie einer Temperaturanzeige (ebenfalls auf LCD-Display, Zeile 3 und 4, innen und außen) und zusätzlich auf Nixieröhren (nur Innentemperatur). Die Temperaturmessung geschieht über Dallas Sensoren, wobei hier die Typen 18S20 (dieser wird verwendet), DS1822 und auch DS18B20 unterstützt werden.

Da ich anfangs mit der DCF-Geschichte die größten Probleme hatte, habe ich mir den von Markus geposteten Code als Basis genommen. Nach den mir vorschwebenden Änderungen funktioniert die DCF Uhr (derzeit noch ohne RTC_Unterstützung)perfekt. Die Zeit wird sowohl auf dem LCD-Display als auch auf der 7-Segment-Anzeige sauber - und vor allem flackerfrei - angezeigt.

An dieser Stelle noch einemal meine ausdrückliche Anerkennung an Markus, das ist ein hervorragend dolumentierter Code, den sogar ein DAU wie ich es bin, versteht und nachvollziehen kann. Danke dafür!!

Wie sich aber jeder hier denken kann, muss ja noch irgendwo ein Haken sein...richtig, der Haken hängt in der Darstellung der Temperatur...und zwar auf dem LCD-Display.
In Zeile 3 und 4 des LCD-Displays wird die Temperatur angezeigt...aber eben nur extrem flackerig. Für mich sieht es so aus, als würde die Temperaturanzeige nur für 250ms angezeigt, danach werden die beiden Zeilen gelöscht...:fie:

Merkwürdigerweise bleiben die Zeilen 1 und 2 mit Datum und Uhrzeit sauber stehen.:vollkommenauf:


Ich hänge hier mal spaßeshalber meinen Code an, vielleicht hat ja einer von euch eine Idee, wie man das geschickter lösen kann:confused:

Code:
'##############################################################################
' DCF77_und_DS1307.BAS                                         Stand 13.02.2007
' --------------------                                         (C) Markus Fulde
'
' ...
$regfile = "m32adef.dat"                                    ' ATmega 32
$crystal = 8000000                                          ' 8 MHz
$hwstack = 128                                              ' Speicherbereiche Reservieren
$swstack = 128                                              ' Speicherbereiche Reservieren
$framesize = 128                                            ' Speicherbereiche Reservieren
'
' Einbindung des Hardware TWI über die Pins 22 und 23 (SCL und SDA)
'
$lib "i2c_twi.lbx"
'
'------------------------------------------------------------------------------
' Definition von Ressourcen
'------------------------------------------------------------------------------
'
'========== Hardware TWI (I²C) ==========
Sda_port Alias Portc.1
Scl_port Alias Portc.0
'
'========== 1-Wire ======================
'
Config 1wire = Portb.0
'
'------------------------------------------------------------------------------
' Definition von Variablen, Konstaten und Datentypen
'------------------------------------------------------------------------------
'
' ----- DCF77 -----
Dim Dcf77_hour As Byte                                      ' Globale Stundenvariable
Dim Dcf77_min As Byte                                       ' Globale Minutenvariable
Dim Dcf77_sec As Byte                                       ' Globale Sekundenvariable
Dim Dcf77_weekday As Byte                                   ' Globaler Wochentag
Dim Dcf77_day As Byte                                       ' Globale Tagvariable
Dim Dcf77_month As Byte                                     ' Globale Monatsvariable
Dim Dcf77_year As Byte                                      ' Globale Jahresvariable
Dim Lftag As Word                                           ' Variable zur Anzeige des Tag des Jahres
'
' Variablen für 7-Segmentanzeige
'
Dim Sek7seg As Byte                                         ' Variable für 7-Segmentanzeige Sekunden
Dim Sek7segleft As Byte                                     ' Variable für 7-Segmentanzeige Sekunden Zehner
Dim Sek7segright As Byte                                    ' Variable für 7-Segmentanzeige Sekunden Einer
Dim Min7seg As Byte                                         ' Variable für 7-Segmentanzeige Minuten
Dim Min7segleft As Byte                                     ' Variable für 7-Segmentanzeige Minuten Zehner
Dim Min7segright As Byte                                    ' Variable für 7-Segmentanzeige Minuten Einer
Dim Hour7seg As Byte                                        ' Variable für 7-Segmentanzeige Stunden
Dim Hour7segleft As Byte                                    ' Variable für 7-Segmentanzeige Stunden Zehner
Dim Hour7segright As Byte                                   ' Variable für 7-Segmentanzeige Stunden Einer
Dim Mask1 As Byte                                           ' enthält WErt für SAA1064 zur Anzeige (Einer)
Dim Mask2 As Byte                                           ' enthält WErt für SAA1064 zur Anzeige (Zehner)
'
' Variablen für Temperaturmessund mit DS18x20
'
Dim Dsid1(8) As Byte                                        ' 1.SensorID 64 bit (8Byte) incl. CRC als Array
Dim Dsid2(8) As Byte                                        ' 2.SensorID 64 bit (8Byte) incl. CRC als Array
Dim Dsid1scratchpad(9) As Byte                              ' Scratchpad 72 bits (9Byte) als Array, enthält Temperaturdaten
Dim Dsid2scratchpad(9) As Byte                              ' Scratchpad 72 bits (9Byte) als Array, enthält Temperaturdaten
Dim Anzahlsensoren As Byte                                  ' Wieviel Sensoren werden am Bus gefunden
Dim I As Byte                                               ' Schleifenvariable
Dim Dg As Integer                                           ' Variable 1 zur Temperaturberechnung DeziGrad
Dim Dg1 As Integer                                          ' Variable 2 zur Temperaturberechnung Dezimalgrad
Dim Dg2 As Single                                           ' Variable 3 zur Temperaturberechnung Dezimalgrad
Dim Index(3) As Byte                                        ' Variable für Tabelle welcher Sensorty gefunden wurde
Dim Temp1 As String * 5                                     ' Temperatur Sensor 1 als String
Dim Temp2 As String * 5                                     ' Temperatur Sensor 2 als String
Dim Min1 As Byte                                            ' Interner Alarmwert Minimaltemperatur Sensor 1
Dim Max1 As Byte                                            ' Interner Alarmwert Maximaltemperatur Sensor 1
Dim Min2 As Byte                                            ' Interner Alarmwert Minimaltemperatur Sensor 2
Dim Max2 As Byte                                            ' Interner Alarmwert Maximaltemperatur Sensor 2
Dim Config1 As Byte
Dim Config2 As Byte
'
' ----- RTC DS1307 -----
' RTC:  Adressen für das exerne EEPROM
'
Const Rtc_address_write = &B11010000                        ' Adresse des DS1307 = &HD0 (schreiben)
Const Rtc_address_read = &B11010001                         ' Adresse des DS1307 = &HD1 (lesen)

Const Rtc_address_seconds = &H00
Const Rtc_address_minutes = &H01
Const Rtc_address_hours = &H02
Const Rtc_address_day = &H03
Const Rtc_address_date = &H04
Const Rtc_address_month = &H05
Const Rtc_address_year = &H06
Const Rtc_address_control = &H07
'
' ----- SAA1064-ICs -----
' Adressen der 3 Treiberbausteine
'
Const 7seg_address_seconds = &H70                           ' Adressleitung auf GND
Const 7seg_address_minutes = &H74                           ' Adressleitung auf 5/8*Vcc  oder &H72 bei Adressleitung auf 3/8*Vcc (Einstellung mit Poti
Const 7seg_address_hours = &H76                             ' Adressleitung auf Vcc
'
' ----- DCF77 -----
'
Dim Sec_old As Byte                                         ' Schleifenvaraible SoftClock Sec
Sec_old = 99
'
Dim Dcfsec_old As Byte                                      ' Schleifenvariable DCF77 Sec
Dcfsec_old = 99
'
Dim Dcf_sync_count As Byte                                  ' Zähler für Anzahl der Syncs
Dcf_sync_count = 0
'
' ----- Sonstiges -----
'
Dim Temp_byte_1 As Byte                                     ' Temporäre Byte Variable
Dim Temp_integer_1 As Integer                               ' Temporäre Integer Variable
'
' ----- Subroutinen -----
'
Declare Sub Rtc_set_rtc_clock
'
Declare Sub Rtc_set_softclock
'
Declare Sub Rtc_write_control_reg(byval Value As Byte)
'
Declare Sub Anzeige7segment
'
Declare Sub Ds18xauslesen
'
Declare Sub Temp_ds1822
'
Declare Sub Temp_ds1820
'
Declare Sub Temperaturanzeige
'
' ----- Funktionen -----
'
Declare Function Rtc_read_control_reg() As Byte
'
Config Dcf77 = Pind.3 , Timer = 1 , Inverted = 0 , Check = 1 , Update = 1 , Updatetime = 00 , Timer1sec = 1 , Debug = 1 , Gosub = Sectic
'               |        |           |               |          |            |                  |                |          |
Enable Interrupts                                           ' Interrupts aktivieren
Config Date = Dmy , Separator = .                           ' Datumsformat einstellen
'
' ----- Konfiguration LCD Display -----
'
Config Lcd = 16 * 4
Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
Initlcd
Waitms 100
Cls
Cursor Off
Deflcdchar 0 , 2 , 5 , 2 , 32 , 32 , 32 , 32 , 32

'
' ----- Konfiguration für RTC DS1307 -----
'
Config Sda = Sda_port
Config Scl = Scl_port
I2cinit
Config Twi = 100000                                         ' Taktfrequenz 100 kBaud
' TWI gleich einschalten, das macht BASCOM ansonsten erst beim I2CStart
Twcr = &B00000100                                           ' nur TWEN setzen
'
' Anzahl Temperatursensoren bestimmen
'
Anzahlsensoren = 1wirecount()
'
' Überschrift ausgeben auf LCD-Display
'
Locate 1 , 1
Lcd " DCF77-RTC-Temp"
Locate 2 , 1
Lcd " Thomas Goebel"
Locate 3 , 1
If Anzahlsensoren = 1 Then
   Lcd Anzahlsensoren ; " Temp.-Sensor"
Else
   Lcd Anzahlsensoren ; " Temp.-Sensoren"
End If
Locate 4 , 1
Lcd "Maerz 2014"
Wait 5
Cls
'
' 1. SensorID ermitteln und auf Fehler prüfen
'
Dsid1(1) = 1wsearchfirst()                                  'suche ersten Sensor
If Err = 0 Then                                             ' wenn kein Fehler
   Locate 1 , 1
   Lcd "ID1:"
   For I = 1 To 8
      Lcd Hex(dsid1(i))                                     ' 8 Byte der SensorID ausgeben
   Next I
   Locate 2 , 1
   Index(1) = Lookdown(dsid1(1) , Data2 , 3)                ' suche in Tabelle Data2, die aus 3 Elementen besteht, nach dem ersten Byte und speicher diesen Wert in Index(1)
   Lcd Lookupstr(index(1) , Data1)                          ' zeige aus Tabelle Data 1 die Stelle Index(1)
   Locate 3 , 1
   If Dsid1(8) = Crc8(dsid1(1) , 7) Then                    ' wenn empangene CRC gleich berechneter CRC, dann
      Lcd "CRC ok SensorID1"
   Else
      Lcd "CRC Bad Sensor1"
   End If
   Wait 5
End If
'
Cls
'
' 2. SensorID ermitteln und auf Fehler prüfen
'
Dsid2(1) = 1wsearchnext()                                   'nächsten Sensor suchen
If Err = 0 Then                                             ' wenn kein Fehler
   Locate 1 , 1
   Lcd "ID2:"
   For I = 1 To 8
      Lcd Hex(dsid2(i))                                     ' 8 Byte der SensorID ausgeben
   Next I
   Locate 2 , 1
   Index(2) = Lookdown(dsid2(1) , Data2 , 3)                ' suche in Tabelle Data2, die aus 3 Elementen besteht, nach dem ersten Byte und speicher diesen Wert in Index(2)
   Lcd Lookupstr(index(2) , Data1)                          ' zeige aus Tabelle Data 1 die Stelle Index(2)
   Locate 3 , 1
   If Dsid2(8) = Crc8(dsid2(1) , 7) Then                    ' wenn empangene CRC gleich berechneter CRC, dann
      Lcd "CRC ok SensorID2"
   Else
      Lcd "CRC Bad Sensor2"
   End If
   Wait 5
End If
'
Cls
'
Gosub Rtc_set_softclock
'
'
'##############################################################################
' Hauptprogramm
'##############################################################################
'Hier ist die Programmhauptschleife
Do

   '
   For Temp_integer_1 = 1 To 78
      Waitms 10                                             ' Schleife läuft max. 780 ms
      If Sec_old <> _sec Then
         Exit For
      End If
      If Dcfsec_old <> Dcf_sec Then
         Exit For
      End If
   Next
   '
   Waitms 220                                               ' Mit 220 ms ist Sekunde voll
   '
   ' Sekunden updaten
   Sec_old = _sec                                           ' Update SoftClock Sekunden
   Dcfsec_old = Dcf_sec                                     ' Update DCF77 Sekunden
   '
   Temp_byte_1 = Dcf_status And &H80
   '
   ' Prüfung ob SoftClock durch DCF77 synchronisiert (Bit 7 aus Statusbyte)
   '
   If Temp_byte_1 = &H80 Then
      Incr Dcf_sync_count                                   ' Sync-Counter erhören
      ' Zur Kontrolle bei erfolgreichem SYNC Status-Bit zurücksetzen
      Reset Dcf_status.7
      ' Anzahl der erfolgen Sync wird nicht auf LCD ausgeben
      Temp_byte_1 = Makebcd(dcf_sync_count)
      ' DS1307 synchronisieren
      Gosub Rtc_set_rtc_clock
   End If
   '
   ' ----- Datum und Uhrzeit BCD formatieren und formatiert auf LCD ausgeben -----
   '
   Dcf77_hour = Makebcd(_hour)
   Dcf77_min = Makebcd(_min)
   Dcf77_sec = Makebcd(_sec)
   'Lcd Bcd(dcf77_hour) ; ":" ; Bcd(dcf77_min) ; ":" ; Bcd(dcf77_sec)
   Dcf77_weekday = Makebcd(_weekday)
   Cls
   Locate 1 , 1
   Lcd Lookupstr(dcf77_weekday , Wochentag)
   Dcf77_day = Makebcd(_day)
   Dcf77_month = Makebcd(_month)
   Dcf77_year = Makebcd(_year)
   Lftag = Dayofyear()
   Incr Lftag
   Locate 1 , 4
   'Lcd Bcd(dcf77_day) ; "." ; Bcd(dcf77_month) ; "." ; Bcd(dcf77_year) ; " "
   Lcd Date$ ; " T" ; Lftag
   '
   Locate 2 , 1
   Lcd Time$
   '
   Call Anzeige7segment
   '
   ' Zeitzone ausgeben mit Hilfe von Dcf77timezone()
   '
   If Dcf77timezone() = 0 Then                              ' noch nicht synchronisiert oder kein DCF-Empfang
      Locate 2 , 12
      Lcd "NODCF"
   End If
   If Dcf77timezone() = 1 Then                              ' mitteleuropäische Normalzeit
      Locate 2 , 12
      Lcd "     "
      Locate 2 , 12
      Lcd "MEZ"
   End If
   If Dcf77timezone() = 2 Then                              ' mitteleuropäische Sommerzeit
      Locate 2 , 12
      Lcd "     "
      Locate 2 , 12
      Lcd "MESZ"
   End If
   '
   ' Temperatur anzeige
   '
   Call Ds18xauslesen
   Locate 3 , 1
   If Anzahlsensoren = 0 Then Lcd "kein Sensor da?"
   If Anzahlsensoren > 0 Then
      '
      1wverify Dsid1(1)                                     'ersten Sensor ansprechen
      If Err = 1 Then
         Locate 3 , 1
         Lcd "Kein Sensor"
      Elseif Err = 0 Then
         If Dsid1(1) = 34 Or Dsid1(1) = 40 Then
            Gosub Temp_ds1822
         End If
         If Dsid1(1) = 16 Then
            Gosub Temp_ds1820
         End If
         Temp1 = Fusing(dg2 , "#.##")                       'Ergebnis als String in Temp1 abspeichern und ab 2. Nachkommastelle abschneiden
         Locate 3 , 1
         Lcd "intern: " ; Temp1 ; Chr(0) ; "C"
      End If
   End If
   '
   If Anzahlsensoren > 1 Then
      ' 2. Sensor ansprechen
      1wverify Dsid2(1)
      Locate 4 , 1
      If Err = 1 Then
         Locate 4 , 1
         Lcd "Kein Sensor"
      Elseif Err = 0 Then
         If Dsid2(1) = 34 Or Dsid2(1) = 40 Then
            Gosub Temp_ds1822
         End If
         If Dsid2(1) = 16 Then
            Gosub Temp_ds1820
         End If
         Temp2 = Fusing(dg2 , "#.##")                       'Ergebnis als String in Temp1 abspeichern und ab 2. Nachkommastelle abschneiden
         Locate 4 , 1
         Lcd "extern: " ; Temp2 ; Chr(0) ; "C"
      End If
   End If

   '
Loop
'

Sectic:
   NOP
Return

Sub Rtc_write_control_reg(byval Value As Byte)
   I2cstart                                                 ' START-Sequenz senden
   I2cwbyte Rtc_address_write                               ' Daten schreiben initiieren
   I2cwbyte Rtc_address_control                             ' Adresse übertragen
   I2cwbyte Value                                           ' Byte 1 übertragen
   I2cstop                                                  ' STOP-Sequenz
End Sub

Function Rtc_read_control_reg() As Byte
   I2cstart                                                 ' START-Sequenz senden
   I2cwbyte Rtc_address_write                               ' Daten schreiben initiieren
   I2cwbyte Rtc_address_control                             ' Adresse übertragen
   I2cstart                                                 ' START-Sequenz erneut senden
   I2cwbyte Rtc_address_read                                ' Daten lesen initiieren
   I2crbyte Temp_byte_1 , Nack                              ' Byte 1 lesen
   I2cstop                                                  ' STOP-Sequenz
   ' Datenbyte als Rückgabewert übergeben
   Rtc_read_control_reg = Temp_byte_1
End Function

Rtc_set_rtc_clock:
   ' Daten zum Speichern in BCD Format aufbereiten
   Dcf77_hour = Makebcd(_hour)
   Dcf77_min = Makebcd(_min)
   Dcf77_sec = Makebcd(_sec)
   Dcf77_weekday = Makebcd(_weekday)
   Dcf77_day = Makebcd(_day)
   Dcf77_month = Makebcd(_month)
   Dcf77_year = Makebcd(_year)
   ' RTC DS1307 synchronisieren
   I2cstart                                                 ' START-Sequenz senden
   I2cwbyte Rtc_address_write                               ' Daten schreiben initiieren
   I2cwbyte Rtc_address_seconds                             ' Adresse übertragen = &H00
   I2cwbyte Dcf77_sec                                       ' Byte 1 übertragen
   I2cwbyte Dcf77_min                                       ' Byte 2 übertragen
   I2cwbyte Dcf77_hour                                      ' Byte 3 übertragen
   I2cwbyte Dcf77_weekday                                   ' Byte 4 übertragen
   I2cwbyte Dcf77_day                                       ' Byte 5 übertragen
   I2cwbyte Dcf77_month                                     ' Byte 6 übertragen
   I2cwbyte Dcf77_year                                      ' Byte 7 übertragen
   I2cstop                                                  ' STOP-Sequenz
Return

Rtc_set_softclock:
   ' RTC DS1307 auslesen
   I2cstart                                                 ' START-Sequenz senden
   I2cwbyte Rtc_address_write                               ' Daten schreiben initiieren
   I2cwbyte Rtc_address_seconds                             ' Adresse übertragen = &H00
   I2cstart                                                 ' START-Sequenz erneut senden
   I2cwbyte Rtc_address_read                                ' Daten lesen initiieren
   I2crbyte Dcf77_sec , Ack                                 ' Byte 1 lesen
   I2crbyte Dcf77_min , Ack                                 ' Byte 2 lesen
   I2crbyte Dcf77_hour , Ack                                ' Byte 3 lesen
   I2crbyte Dcf77_weekday , Ack                             ' Byte 4 lesen
   I2crbyte Dcf77_day , Ack                                 ' Byte 5 lesen
   I2crbyte Dcf77_month , Ack                               ' Byte 6 lesen
   I2crbyte Dcf77_year , Nack                               ' Byte 7 lesen und fertig (NACK)
   I2cstop                                                  ' STOP-Sequenz
   ' ausgelesene Daten in SoftClock Variablen übernehmen
   _hour = Makedec(dcf77_hour)
   _min = Makedec(dcf77_min)
   _sec = Makedec(dcf77_sec)
   _weekday = Makedec(dcf77_weekday)
   _day = Makedec(dcf77_day)
   _month = Makedec(dcf77_month)
   _year = Makedec(dcf77_year)
Return

Anzeige7segment:
   '
   Sek7seg = _sec
   Min7seg = _min
   Hour7seg = _hour

   Hour7segleft = Hour7seg / 10
   Hour7segright = Hour7seg Mod 10
   Mask2 = Lookup(hour7segleft , Display7seg)
   Mask1 = Lookup(hour7segright , Display7seg)
   ' Stunden
   I2cstart                                                 ' START-Sequenz senden
   I2cwbyte &H76                                            ' Adresse übertragen = &H76 für Stunden
   I2cwbyte 0                                               ' instruction byte
   I2cwbyte &H16                                            ' control byte
   I2cwbyte Mask1                                           ' Mask1 (Einerstelle)
   I2cwbyte Mask2                                           ' Mask2 (Zehnerstelle)
   I2cstop
   ' Minuten
   Min7segleft = Min7seg / 10
   Min7segright = Min7seg Mod 10
   Mask2 = Lookup(min7segleft , Display7seg)
   Mask1 = Lookup(min7segright , Display7seg)

   I2cstart                                                 ' START-Sequenz senden
   I2cwbyte &H74                                            ' Adresse übertragen = &H74 für Minuten
   I2cwbyte 0                                               ' instruction byte
   I2cwbyte &H16                                            ' control byte
   I2cwbyte Mask1                                           ' Mask1 (Einer)
   I2cwbyte Mask2                                           ' Mask2 (Zehner)
   I2cstop
   '
   Sek7segleft = Sek7seg / 10
   Sek7segright = Sek7seg Mod 10
   Mask2 = Lookup(sek7segleft , Display7seg)
   Mask1 = Lookup(sek7segright , Display7seg)

   I2cstart                                                 ' START-Sequenz senden
   I2cwbyte &H70                                            ' Adresse übertragen = &H70 für Sekunden
   I2cwbyte 0                                               ' instruction byte
   I2cwbyte &H16                                            ' control byte
   I2cwbyte Mask1                                           ' Mask1 (Einer)
   I2cwbyte Mask2                                           ' Mask2 (Zehner)
   I2cstop
   '
Return

Temp_ds1822:
   1wwrite &HBE                                             ' Kommando Scratchpad auslesen
   Dsid1scratchpad(1) = 1wread(9)                           ' lese 9 Bytes in das Array (byte9=Checksumme)
   If Dsid1scratchpad(9) = Crc8(dsid1scratchpad(1) , 8) Then       'Überprüfung Checksumme, wenn okay, dann...
      Dg = Makeint(dsid1scratchpad(1) , Dsid1scratchpad(2)) ' 1. und 2. Byte (LSB+MSB) zusammenfügen
      'Dg2=Dg*100
      Dg = Dg * 100
      Dg2 = Dg / 16
   End If
Return

Temp_ds1820:
   1wwrite &HBE                                             ' Kommando Read Scratchpad
   Dsid2scratchpad(1) = 1wread(9)                           ' 9 Bytes in das Array einlesen
   If Dsid2scratchpad(9) = Crc8(dsid2scratchpad(1) , 8) Then       'Checksumme prüfen
      I = Dsid2scratchpad(1) And 1
      If I = 1 Then Decr Dsid2scratchpad(1)
      Dg = Makeint(dsid2scratchpad(1) , Dsid2scratchpad(2))
      Dg = Dg * 50
      Dg = Dg - 25
      Dg1 = Dsid2scratchpad(8) - Dsid2scratchpad(7)
      Dg1 = Dg1 * 100
      Dg1 = Dg1 / Dsid2scratchpad(8)
      Dg = Dg + Dg1
      Dg2 = Dg / 100
      Dg2 = Dg2 - 1.1                                       ' Korrektur mit Vergleichsthermometer
   End If
Return

Ds18xauslesen:
   1wreset
   1wwrite &HCC                                             ' Skip Rom ==> alle Sensoren ansprechen
   1wwrite &H44                                             ' Convert T
   Waitms 750                                               ' Zeit geben für Temperaturmessung
Return

'
End                                                         'end program

Wochentag:
   Data "  " , "Mo" , "Di" , "Mi" , "Do" , "Fr" , "Sa" , "So"
   '
Display7seg:
   Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F
   '
Data1:
   Data " " , "DS1822" , "DS18S20" , "DS18B20"
   '
Data2:
   Data 34 , 16 , 40
'
'###################################### END ###################################

So...ich wünsche euch noch ein schönes Wochenende, mir raucht für heute der Kopf...

Gruß
Thomas
 
Hi,

irgendwo läßt Du das Display bei jedem Hauptschleifendurchlauf komplett löschen (CLS). Die Sensorangaben werden dann als letztes geschrieben. Mit den ganzen Ausleseoperationen der Sensoren (Zeit, DCF, Temp) und dem Schreiben aufs Display wird schon einiges zusammenkommen.
Warum verzichtest Du nicht auf das CLS, und überschreibst stattdessen nur die Daten, und das auch nur dann, wenn sich da was geändert hat?
 
Hallo LotadaC,

vielen Dank für deinen Hinweis, aber wenn dem so wäre, dann würden ja die Zeilen 1 und 2 ebenfalls "blinken".

Es irritiert mich fürchterlich, dass ausschließlich Zeile 3 und 4 jeweils nur für geschätzte 250ms angezeigt werden....die restlichen 750ms sind dort einfach zwei leere Zeilen.

Ich weiß, das ist schwer vorstellbar, ich konnte das auch nicht glauben, aber es ist einfach so...

Während der Hauptschleife (do...loop) wird meines Wissens nach auch in den aufgerufenen Unterprogrammen kein CLS aufgerufen.

Gruß
Thomas
 
Code:
...
'##############################################################################
' Hauptprogramm
'##############################################################################
'Hier ist die Programmhauptschleife
Do

   '
   For Temp_integer_1 = 1 To 78
      Waitms 10                                             ' Schleife läuft max. 780 ms
      If Sec_old <> _sec Then
         Exit For
      End If
      If Dcfsec_old <> Dcf_sec Then
         Exit For
      End If
   Next
   '
   Waitms 220                                               ' Mit 220 ms ist Sekunde voll
   '
   ' Sekunden updaten
   Sec_old = _sec                                           ' Update SoftClock Sekunden
   Dcfsec_old = Dcf_sec                                     ' Update DCF77 Sekunden
   '
   Temp_byte_1 = Dcf_status And &H80
   '
   ' Prüfung ob SoftClock durch DCF77 synchronisiert (Bit 7 aus Statusbyte)
   '
   If Temp_byte_1 = &H80 Then
      Incr Dcf_sync_count                                   ' Sync-Counter erhören
      ' Zur Kontrolle bei erfolgreichem SYNC Status-Bit zurücksetzen
      Reset Dcf_status.7
      ' Anzahl der erfolgen Sync wird nicht auf LCD ausgeben
      Temp_byte_1 = Makebcd(dcf_sync_count)
      ' DS1307 synchronisieren
      Gosub Rtc_set_rtc_clock
   End If
   '
   ' ----- Datum und Uhrzeit BCD formatieren und formatiert auf LCD ausgeben -----
   '
   Dcf77_hour = Makebcd(_hour)
   Dcf77_min = Makebcd(_min)
   Dcf77_sec = Makebcd(_sec)
   'Lcd Bcd(dcf77_hour) ; ":" ; Bcd(dcf77_min) ; ":" ; Bcd(dcf77_sec)
   Dcf77_weekday = Makebcd(_weekday)
 [B][COLOR="#B22222"]  Cls[/COLOR][/B]
   Locate 1 , 1
   Lcd Lookupstr(dcf77_weekday , Wochentag)
   Dcf77_day = Makebcd(_day)
   Dcf77_month = Makebcd(_month)
   Dcf77_year = Makebcd(_year)
   Lftag = Dayofyear()
   Incr Lftag
   Locate 1 , 4
   'Lcd Bcd(dcf77_day) ; "." ; Bcd(dcf77_month) ; "." ; Bcd(dcf77_year) ; " "
   Lcd Date$ ; " T" ; Lftag
   '
   Locate 2 , 1
   Lcd Time$
   '
   Call Anzeige7segment
   '
   ' Zeitzone ausgeben mit Hilfe von Dcf77timezone()
   '
   If Dcf77timezone() = 0 Then                              ' noch nicht synchronisiert oder kein DCF-Empfang
      Locate 2 , 12
      Lcd "NODCF"
   End If
   If Dcf77timezone() = 1 Then                              ' mitteleuropäische Normalzeit
      Locate 2 , 12
      Lcd "     "
      Locate 2 , 12
      Lcd "MEZ"
   End If
   If Dcf77timezone() = 2 Then                              ' mitteleuropäische Sommerzeit
      Locate 2 , 12
      Lcd "     "
      Locate 2 , 12
      Lcd "MESZ"
   End If
   '
   ' Temperatur anzeige
   '
   Call Ds18xauslesen
   Locate 3 , 1
   If Anzahlsensoren = 0 Then Lcd "kein Sensor da?"
   If Anzahlsensoren > 0 Then
      '
      1wverify Dsid1(1)                                     'ersten Sensor ansprechen
      If Err = 1 Then
         Locate 3 , 1
         Lcd "Kein Sensor"
      Elseif Err = 0 Then
         If Dsid1(1) = 34 Or Dsid1(1) = 40 Then
            Gosub Temp_ds1822
         End If
         If Dsid1(1) = 16 Then
            Gosub Temp_ds1820
         End If
         Temp1 = Fusing(dg2 , "#.##")                       'Ergebnis als String in Temp1 abspeichern und ab 2. Nachkommastelle abschneiden
         Locate 3 , 1
         Lcd "intern: " ; Temp1 ; Chr(0) ; "C"
      End If
   End If
   '
   If Anzahlsensoren > 1 Then
      ' 2. Sensor ansprechen
      1wverify Dsid2(1)
      Locate 4 , 1
      If Err = 1 Then
         Locate 4 , 1
         Lcd "Kein Sensor"
      Elseif Err = 0 Then
         If Dsid2(1) = 34 Or Dsid2(1) = 40 Then
            Gosub Temp_ds1822
         End If
         If Dsid2(1) = 16 Then
            Gosub Temp_ds1820
         End If
         Temp2 = Fusing(dg2 , "#.##")                       'Ergebnis als String in Temp1 abspeichern und ab 2. Nachkommastelle abschneiden
         Locate 4 , 1
         Lcd "extern: " ; Temp2 ; Chr(0) ; "C"
      End If
   End If

   '
Loop
...
Ob das jetzt was damit zu tun hat, kann ich nicht sagen, aber zwischendurch callst Du ja erst noch die 7-Segmentausgabe.
Danach callst Du die Sensoren, und danach werden erst die letzten beiden Zeilen geschrieben.
Was da nun wielange dauert... kA.

Kommentier doch versuchsweise einfach mal ganze Blöcke aus, und sehe dann weiter (als die komplette Siebensegmentausgabe, das Schreiben der Uhrzeit usw)
Andere Sache: Auch während der vorhergehenden Init-Phase löscht Du mehrfach das LCD... dann brauchst Du doch auch nichts schreiben... oder soll das so'n Info-Splash-Screen sein?
 
Ohje...da hab ich doch glatt ein CLS übersehen....Asche über mein Haupt:p

Jetzt hab ich das mal rausgenommen....und siehe da, die Anzeige flackert nicht mehr...aber unglücklicherweise ist das CLS für einen sauberen Aufbau der Anzeige notwendig.

Werde das in den nächsten Tagen mal in Abhängigkeit von der Synchronisierung rausnehmen...hoffentlich klappt das so, wie ich mir das dann vorstelle.

Nochmals vielen Dank für die Hilfe

Gruß
Thomas
 
aber unglücklicherweise ist das CLS für einen sauberen Aufbau der Anzeige notwendig.

Außer beim (Power-On) Reset sollte ein CLS eigentlich nie nötig sein, zumal der Befehl relativ gesehen sehr lange braucht.
Wo ich jetzt schon Fehler sehe wären z. B. die Zeilen:
Code:
    Locate 2 , 12
    Lcd "NODCF"
    ...
    Lcd "MEZ"
    ...
    Lcd "MESZ"

Die Strings sind unterschiedlich lang, also kann es passieren dass du "Schmutz" von früher nicht mit weg "putzt". Ein paar Leerzeichen lösen das Problem (hier mit _ ersetzt, weil deutlicher):
Code:
    Lcd "NODCF"
    ...
    Lcd "MEZ__"
    ...
    Lcd "MESZ_"

Dieses "überschreiben" ist um Längen schneller und flacker-freier als ständig ein CLS auszuführen.
Ich habe jetzt nicht dein komplettes Programm durchgesehen, vielleicht gibt es so etwas noch an anderen Stellen.
 
Hallo TommyB,

danke für die Hinweise....hab ich grade mal geändert.....sehr hilfreich diese Tips....vielen Dank

Gruß
Thomas
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)