Erledigt ATMega8 Uhr Temparatur Anzeige

Was willst Du denn jetzt hören?
Derzeit hast Du Dir mit Timer1 quasi einen Wecker gestellt, jede Sekunde (circa) liest Du daraufhin die RTC aus, stellst anhand der Sekunde (oh welch Überraschung) fest, daß die RTC-Zeit neu gegenüber der letzten ist, berechnest die Zeit (dezimal), und merkst Dir das mit 'nem Counter fürs Hauptprogramm.
Im Hauptprogramm reagierst Du auf den Counter: stellst erst die Zeit, dann die Temperatur je 3s lang dar usw.
Die Pause realisierst Du mit wait, der Schleifendurchlauf wird also 6s lang angehalten. D.h.: die Anzeige zeigt 3s lang 'ne "stehende" Zeit an, dann 3s lang die "stehende" Temperatur, inzwischen hat der Timer im Hintergrund den Counter hochgezählt - also wird beim nächsten Schleifendurchlauf die neue Zeit dargestellt - ein 6s-Sprung...

Warum stellst Du nicht beides gleichzeitig dar, mit 4 Zeilen?

Überdenk doch mal Dein ganzes Konzept, und stell Dir erstmal einen Programmablaufplan zusammen. Unabhängig von der LCD-Anbindung...

Mein Vorschlag ist bereits in #15 angedeutet.

Ansonsten hast Du einige unnötig komplizierte Sachen drinn (Timer-Reload, das Byte-invertieren (134..136)...)
 
Hallo,

@LotadaC hat es schon geschrieben. Wie kann man dich helfen, wenn ständig neue Hardware- Varianten kommen aber immer die gleiche Frage Zitat: „der weschel zwischen Uhr und der temparatur ist nicht obtimal was oder wie ändern.....“.
Frage: Was ist nicht optimal. Optimal ist wohl eine Weltanschauung.
Antwort: Eins ist sicher, dein Code ist es auf keinem Fall. Na klar hat jeder seine eigene Handschrift, aber das „kleine ABC“ sollte schon beachtet werden.

Würde gern weiter helfe aber so nicht (hier und da mal ein Timer starten und dann noch ein Interrupt dazwischen knallen ist für mich zu hoch. Kannst mir gerne dein Programmablauf erklären. Bin noch lernfähig.

Wünsche Erfolg.
Fred
 
Ja die Aller besten programierer sind immer die mit der großen klappe die können es ja, aber wehe es geht um einen der das noch nicht soch recht
drauf hat wird immer wieder gesagt oh mach doch wie willst.....

Nur zu infomation

ich habe nu ein 4x20LCD in 4Bit und den DS1307 An I2C Hängen und es läuft soweit ganz gut nur das die temparatur ab und zu bis zu
1200 springt und dann wieder die nomal Temparatur

hier der code noch mal wie er jetzt ist


CodeBox BascomAVR
$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40

'tasten
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1
Portc.3 = 1
S1 Alias Pinc.0
S2 Alias Pinc.1
S3 Alias Pinc.2
S4 Alias Pinc.3

'LCD
Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4 , Db7 = Portd.5 , _
E = Portd.6 , Rs = Portd.7
Config Lcd = 20 * 4 , Chipset = St7032                      'Type 20 x 4 Blau LCD ST7032                                          ', Chipset = St7032                      'Ks077                       'Einstellen des LCD 16x2 oder 20x4
Config Lcdbus = 4
Cls                                                         'LCD Leeren
Cursor Off

'Adresse DS1307
'Adresse DS1307
Const Ds1307w = &HD0
Const Ds1307r = &HD1
I2cinit

'Config I2cdelay = 15                                        'delay von 15=20µs=50kHz,10=10µs=100kHz;5=5µs=200KHz
Config Scl = Portc.5                                        'I2C SCL Pin
Config Sda = Portc.4                                        'I2C SDA Pin

Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32           ' Punkt Oben Rechts

Config 1wire = Portb.0                                      'Pin fuer 1Wire festlegen

Config Timer1 = Timer , Prescale = 256                      'Timer für Sekundentakt zum
On Timer1 Sectic                                            'abfragen der RTC
Const Ladetimer1 = 22336
Enable Timer1

Config Date = Dmy , Separator = .                           'Trennzeichen Datumsformat einstellen
Config Clock = User
Dim Weekday As Byte

Dim L_sec As Byte , Print_lcd As Byte , Setmode As Byte
Dim Wert_aus_ds1820 As Integer                              'Register 2 Byte lang auslesen
Dim Ganze_grad As Word , Halbegrad As Byte
Dim Temperatur As Single
Dim I As Byte

Cls
Locate 1 , 1
Lcd "UHR - TEMPARATUR"
Locate 2 , 1
Lcd "DS1307 & DS18S20"
Wait 2
Cls

Enable Interrupts

Do
 Debounce S1 , 0 , Goto_setmode , Sub

 If Setmode = 1 Then
  Debounce S2 , 0 , Sethour , Sub
  Debounce S3 , 0 , Setmin , Sub
  Debounce S4 , 0 , Setsecond , Sub
 End If

 If Setmode = 2 Then
  Debounce S2 , 0 , Setday , Sub
  Debounce S3 , 0 , Setmonth , Sub
  Debounce S4 , 0 , Setyear , Sub
 End If


 If Print_lcd > 0 And Setmode = 0 Then
  Locate 1 , 1
  Lcd Time$ ; " Uhr"
  Locate 2 , 1
  Lcd Date$ ; " Datum"
  Print_lcd = 0
  If Halbegrad = 1 Then Temperatur = Temperatur + 0.5
  Locate 4 , 6
  Lcd Temperatur ; "  C" ; Chr(0)
  Wait 1
 End If

 If Setmode = 2 Then
  Upperline
  Lcd Time$ ; "   SET"
  Lowerline
  Lcd Date$ ; "  >DATE<"
 End If

 If Setmode = 1 Then
  Upperline
  Lcd Time$ ; "   SET"
  Lowerline
  Lcd Date$ ; "  >TIME<"
 End If

1wreset
1wwrite &HCC                                                'Bausteinauswahl ignorieren
1wwrite &H44                                                'Messvorgang anstossen
Waitus 80
1wreset
1wwrite &HCC                                                'Bausteinauswahl ignorieren
1wwrite &HBE                                                'Read Scratchpad
Wert_aus_ds1820 = 1wread(2)                                 '2 Bytes lesen: MSB, LSB
1wreset

Halbegrad = Wert_aus_ds1820.0                               'wenn 1: spaeter 0,5 addieren

Shift Wert_aus_ds1820 , Right                               'Bit 0 rausschieben


If Wert_aus_ds1820.7 = 0 Then
'  --  >= Null Grad
  Temperatur = Wert_aus_ds1820
Else
'  -- Minus-Temperatur
'  -- Zweierkomplement bilden:
  Wert_aus_ds1820 = Wert_aus_ds1820 And &B0000000011111111
  Decr Wert_aus_ds1820                                      '1 subtrahieren

  For I = 0 To 7                                            'jedes Bit invertieren
    Toggle Wert_aus_ds1820.i
  Next

  Temperatur = -wert_aus_ds1820                             'Vorzeichen setzen
End If
Loop

Goto_setmode:
  Incr Setmode
  If Setmode > 2 Then
    Setmode = 0
  End If
  Cls
Return

Set_date_mode:
 If Setmode = 0 Then
   Setmode = 2
  Else
   Setmode = 0
   Cls
  End If
Return

Setday:
 Incr _day
 If _day > 31 Then _day = 1
 Gosub Setdate
Return

Setmonth:
 Incr _month
 If _month > 12 Then _month = 1
 Gosub Setdate
Return

Setyear:
 Incr _year
 If _year > 99 Then _year = 0
 Gosub Setdate
 Gosub Getdatetime
Return

Sethour:
 Incr _hour
 If _hour > 23 Then _hour = 0
 Gosub Settime
Return

Setmin:
 Incr _min
 If _min > 59 Then _min = 0
 Gosub Settime
Return

Setsecond:
 _sec = 0
 Gosub Settime
Return

Sectic:
 If Setmode = 0 Then
   Timer1 = Ladetimer1
   Gosub Getdatetime
 End If
 If _sec <> L_sec Then
  L_sec = _sec
  Incr Print_lcd
 End If
Return

'called from ds1307clock.lib
Getdatetime:
  I2cstart                                                  ' Generate start code
  I2cwbyte Ds1307w                                          ' send address
  I2cwbyte 0                                                ' start address in 1307
  I2cstart                                                  ' Generate start code
  I2cwbyte Ds1307r                                          ' send address
  I2crbyte _sec , Ack
  I2crbyte _min , Ack                                       ' MINUTES
  I2crbyte _hour , Ack                                      ' Hours
  I2crbyte Weekday , Ack                                    ' Day of Week
  I2crbyte _day , Ack                                       ' Day of Month
  I2crbyte _month , Ack                                     ' Month of Year
  I2crbyte _year , Nack                                     ' Year
  I2cstop
  _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
  _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
Return

Setdate:
  _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
  I2cstart                                                  ' Generate start code
  I2cwbyte Ds1307w                                          ' send address
  I2cwbyte 4
  I2cwbyte _day                                             ' Send Data to SECONDS
  I2cwbyte _month                                           ' MINUTES
  I2cwbyte _year                                            ' Hours
  I2cstop
Return

Settime:
  _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
  I2cstart                                                  ' Generate start code
  I2cwbyte Ds1307w                                          ' send address
  I2cwbyte 0                                                ' starting address in 1307
  I2cwbyte _sec                                             ' Send Data to SECONDS
  I2cwbyte _min                                             ' MINUTES
  I2cwbyte _hour                                            ' Hours
  I2cstop
Return

Kann man da was verbessern oder jemand dazu Tipps geben?
Vielen dank
 
Oh, Oh nun hast du dich wohl im Ton vergriffen. Ja mag sein es gibt noch welche die deine (abgekupferte Code zusammen gewürfelt und als eigen bezeichneten ) toll finden. Ich bin halt zu blöd dich zu helfen. Ist ja OK.

Somit kann ich mich nur für Hilfsversuche entschulligen.
Werde mich nun von Thread verabschieden.

Gruß und Tschüß

Fred
 
  • Like
Reaktionen: TommyB
aber wehe es geht um einen der das noch nicht soch recht
drauf hat wird immer wieder gesagt oh mach doch wie willst.....
Nein...
Ich habe mehrfach vorgeschlagen, daß Du uns erstmal Dein Konzept - eben einen Ablaufplan gibst, sodaß man bereits das Konzept optimieren kann, BEVOR man damit anfängt, den Code zu optimieren, der dem Konzept dann folgen soll.
Ich habe ferner ein eigenes Konzept angedeutet - hast Du alles ignoriert.
Jetzt hast Du immerhin die 6s Pause korrigiert (warum aber noch eine??).

Wie gesagt finde ich das ganze Konzept so unausgegoren, aber ok:
Kann man da was verbessern oder jemand dazu Tipps geben?
Natürlich!
  • Timer1 kann sich statt des Preloads selbst zurücksetzen (Waveform Generation Mode 4 oder 12 bzw äquivalente PWM-Modi)
  • Temperaturmessung starten und auslesen folgen nahezu direkt aufeinander - kann man doch sicher innerhalb der Hauptschleife trennen
  • Vollkommen verwurstelt ist die Umrechnerei der Temperaturdaten. Wenn eine negative Temp ausgelesen wird, multiplizierst Du salopp gesagt zweimal mit -1 (einmal zu Fuß (124..132), und dann direkt (134). Abgesehen davon konvertierst Du dabei eine Integer- in eine Single-Variable. Warum überhaupt single? Nur für die eventuellen halben Kelvin?
  • Und als wäre das noch nicht genug, setzt Du dem ganzen mit dem umkippen der Bits des Low-Bytes noch die Krone auf.
Ist Dir eigentlich klar, was'ne Integervariable ist (warum Du für "Wert_aus_ds1820" eine verwendet hast), und was Dir der Sensor konkret liefert??

(Das "Grad" steht vor dem "Celsius")
 
Zuletzt bearbeitet:
Und ich sag's nochmal, der Temperatursensor braucht mehr Zeit als 0,08 milliSekunden um die Temperatur zu messen. 0,7 Sekunden bei voller Auflösung hab' ich im Gedächtnis.
 
Im Datenblatt finde ich nur "maximal 750ms".
Wenn der Sensor non-parasite-powered ist, kann man den Status der laufenden Messung auch "abfragen":
after the Convert T command and the DS18S20 will respond by transmitting 0 while the temperature conversion is in progress and 1 when the conversion is done. If the DS18S20 is powered with parasite power, this notification technique cannot be used since the bus must be pulled high by a strong pullup during the entire temperature conversion.
Aber wie gesagt: jede Sekunde Lesen, und dann 'ne Messung für die nächste anstoßen wäre das einfachste...
 
Klar, er könnte früher fertig sein, muss aber nicht, nur nach 750 mSec ist er aber sicher fertig. Beim DS18B20 gab's noch eine Tabelle für die Messzeit, abhängig von der Auflösung.
 
Beim "B" kannst Du die Auflösung mit den Resolution-Bits im Konfigurationsregister ja auch einstellen, und hast unterschiedliche maximale(!) Konversionszeiten (93,75ms@9bit..750ms@12bit).
Der "S" arbeitet immer(!) mit 12bit, und braucht demzufolge immer max 750ms. Aus Kompatibilitätsgründen zum DS1820 (ohne Buchstabe) liefert er beim auslesen der Temp-Register nur 9 Bit - die restlichen Bits kann man aber aus den beiden Count-Registern rekonstruieren.
nur nach 750 mSec ist er aber sicher fertig
eben...
Aber wie gesagt: jede Sekunde Lesen, und dann 'ne Messung für die nächste anstoßen wäre das einfachste...

OT @Dirk : danke für das Reorganisationsfeature bei den Multi-Zitaten...
 

Ü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)