I2C TM1637 + RTC 1307

maikgen

Mitglied
24 Mrz 2010
45
0
6
Sprachen
Hallo
Ich versuche mich gerade etwas in Sachen I2C und Bascom
meine Plan ist es eine Kleinen Mega zunutzen um mir eine Zeit auf ein 7 Segment Display anzeigen zulassen, zusätzlich noch die Temp mit einem/zwei DS1820b und dies in ein Moped einzubauen das ich beim fahren immer eine Zeit habe sowie die Temperatur
Ich habe mir eine RTC 1307 geholt diese ist nach DCF-77 gestellt dies geht soweit ganz gut.
zusätztlich habe ich mir ein TM1637 geholt ( habe schon gelesen das das nicht so einfach sein soll aber es funktioniert es zeigt mir die Zeit an welche es über DCF-77 bekommt und auch die Temperaturen der DS1820b Sensoren. Soweit sogut.

Also beide Programme einzeln funktionieren super.
wie bekomme ich es jetzt hin das ich beide I2C teile in ein Programm bekomme. Habe im Forum nicht wirklich was gefunden. oder soll ich mir ein andere 7-Segment Display besorgen wenn welches.



CodeBox BascomAVR
'RTC 1307 auslesen nur Uhrzeit

$regfile = "m32def.dat"   'Atmega32
$crystal = 16000000       '16MHZ
$hwstack=40
$swstack=16
$framesize=32

'Display einstellen
Config Lcd = 16 * 4
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , _
Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
Initlcd
Cls

'Display beleuchtung einschalten
Config Timer0 = Pwm ,  Compare Pwm = Clear up , Prescale = 256
Config Portb.3 = Output
OCR0 = 250


CONFIG CLOCK = soft

Enable Interrupts

'I2C einstellen SCL = Port C.0 und SDA = Port C.1
Config Scl = Portc.0
Config Sda = Portc.1


Dim Sekunde As Byte
Dim Minute As Byte
Dim Stunde As Byte

Dim Ds1307w As Byte
Dim Ds1307r As Byte

Ds1307w = &B11010000
Ds1307r = &B11010001

Declare Sub auslesen

Do

Locate 1 , 1
Lcd Time$

Call Auslesen   'Auslesen starten

Loop

End


'Uhrzeit aus RTC auslesen ohne Datum nur Zeit
SUB Auslesen

_Sec = Makedec(sekunde)
_min = Makedec(minute)
_hour = Makedec(stunde)

I2cstart
I2cwbyte Ds1307w
I2cwbyte 0
I2cstop
I2cstart
I2cwbyte Ds1307r
I2crbyte Sekunde , Ack
I2crbyte Minute , Ack
I2crbyte Stunde , Nack
I2cstop

END SUB Auslesen


das ist mein Teil für die RTC

Und hier der Teil für da TM1637



CodeBox BascomAVR
$Regfile="m32def.dat"
$Crystal=16000000
$hwstack=40
$swstack=16
$framesize=32


config Portc.0 = output
config Portc.1 = output
Clk Alias Portc.0

Dio_set Alias Portc.1
Dio_out Alias Portc.1
Dio_in Alias Pinc.1

Match_rom Alias &H55
Skip_rom Alias &HCC
Auslesen Alias &HBE
Messen Alias &H44

DdrA = &B0000000


Declare Sub Tm1637_wrbyte(byval Bajt As Byte)
declare Sub Tm1637_start
declare Sub Tm1637_ack
declare Sub Tm1637_stop
Declare Sub Funkuhr
declare Sub Einzelzeit
Declare Sub Tempmessung


Config Dcf77 = PinB.0 , Timer = 1 , Debug = 1 , Check = 1 , Inverted = 0 , Gosub = Sectic


'Tempvariable
Dim T10 As Integer , T20 As Integer      'für min max berechnung
dim einerT1 as byte , einerT2 as byte , zehnT1 as byte , zehnT2 as byte
dim ceinerT1 as byte , ceinerT2 as byte , czehnT1 as byte , czehnT2 as byte
Dim Ds1820id(16) As Byte , Sc(9) As Byte                    'Anzahle sensoren 8 = 1  16 = 2 , 24 = 3 , 32 = 4  ,40 = 5  , 48 = 6 , 54 = 7
Dim I As Byte
Dim Dgc As Integer
Dim T1 As Integer , T2 As Integer

'Uhr Variable
Dim temp as byte
Dim Dezimalziffern(4) as  byte
Dim Zehnerh as byte , zehnermin as byte
Dim einerh as byte , Einermin as byte , Einerhpunkt as byte
Dim Zehnerhzeit as Byte , Einerhzeit as byte , Zehnerminzeit as byte ,   Einerminzeit as byte
Dim Takt as byte , Takt_alt as byte
Dim Punktzeit as byte


call Tm1637_start
Call Tm1637_wrbyte(&H89)            ' Hex 80=off; Hex 88= 1/16 brightness to Hex 8F = Maximun Brightness
call Tm1637_ack
call Tm1637_stop


Enable Interrupts


Config  1WIRE = PortA.6                       '1Wire-Port festlegen war mal Port C.1

Declare Function Decigrades18b20(byval Sc(9) As Byte) As Integer       'für DS18b20 ( China Sensoren )

Restore Sensor_ids
For I = 1 To 17
   Read Ds1820id(i)
Next I
1wreset
1wwrite Skip_rom
1wwrite Messen

Do

If Punktzeit >= 2 then Punktzeit = 0
Call einzelzeit                                           'Funkuhr / Zeitberechnungsunterprogramm starten
Call Tempmessung

'Zeit Anzeige
Zehnerhzeit = Lookup(zehnerh , Ziffern_pattern)  'Lookup holt aus den Daten unter Ziffern_pattern aus Tabelle
If Punktzeit = 1 then Einerhzeit = Lookup(einerh , Ziffern_pattern)       'Doppelpunkt blinkenlassen
If Punktzeit = 0 then Einerhzeit = Lookup(einerhpunkt , Ziffern_pattern)  'Doppelpunkt blinkenlassen
Zehnerminzeit = Lookup(zehnermin , Ziffern_pattern)  'Lookup holt aus den Daten unter Ziffern_pattern aus Tabelle
Einerminzeit = Lookup(einermin , Ziffern_pattern)    'Lookup holt aus den Daten unter Ziffern_pattern aus Tabelle

'Temp Anzeige
czehnT1 =  Lookup(ZehnT1 , Ziffern_pattern)
ceinerT1 = Lookup(einerT1 , Ziffern_pattern)
czehnT2 =  Lookup(ZehnT2 , Ziffern_pattern)
ceinerT2 = Lookup(einerT2 , Ziffern_pattern)

'Zeit Anzeige
If _Sec <20 or _Sec >= 50 then                             'Hier wird die Zeit angezeigt
    call Tm1637_start
    Call Tm1637_wrbyte(&H40)                                'Data instruction set Hex44 write one byte to register (data write mode set) autoincrement adress mode
    call Tm1637_ack
    call Tm1637_stop
'
    call Tm1637_start
    Call Tm1637_wrbyte(&Hc0)                                'addres instruction setting, first digit (HexC0) MSB display
    Call Tm1637_ack
    'erste Stelle
    Call Tm1637_wrbyte(Zehnerhzeit)
    Call Tm1637_ack
    'zweite Stelle
    Call Tm1637_wrbyte(Einerhzeit)
    Call Tm1637_ack
    'dritte Stelle
    Call Tm1637_wrbyte(Zehnerminzeit)
    Call Tm1637_ack ' Gosub
    'vierte Stelle
    Call Tm1637_wrbyte(Einerminzeit)
    Call Tm1637_ack
    Call Tm1637_stop
End if


'Temp1 Anzeige
If _Sec >=20 and _sec < 35 then
    'We want to display 1234
    call Tm1637_start
    Call Tm1637_wrbyte(&H40)                                'Data instruction set Hex44 write one byte to register (data write mode set) autoincrement adress mode
    call Tm1637_ack
    call Tm1637_stop
'
    call Tm1637_start
    Call Tm1637_wrbyte(&Hc0)                                'addres instruction setting, first digit (HexC0) MSB display
    call Tm1637_ack
    'erste Stelle
    Call Tm1637_wrbyte(czehnT1)                                   'Digit 1; showing:1
    call Tm1637_ack
    'zweite Stelle
    Call Tm1637_wrbyte(ceinerT1)                                   'Digit 2; showing:2
    call Tm1637_ack
    'dritte Stelle
    Call Tm1637_wrbyte(&B01100011)                                   'Digit 3; showing:3
    call Tm1637_ack
    'vierte Stelle
    Call Tm1637_wrbyte(&B00111001)                                   'Digit 4; showing:4
    call Tm1637_ack
    call Tm1637_stop
End if

'Temp2 Anzeige
If _Sec >=35 and _sec < 50  then
   'We want to display (empty)008
    call Tm1637_start
    Call Tm1637_wrbyte(&H40)                                'Data instruction set Hex44 write one byte to register (data write mode set) autoincrement adress mode
    call Tm1637_ack
    call Tm1637_stop
'
    call Tm1637_start
    Call Tm1637_wrbyte(&Hc0)                                'addres instruction setting, first digit (HexC0) MSB display
    Call Tm1637_ack
    'erste Stelle
    Call Tm1637_wrbyte(czehnT2)                                   'Digit 1; showing:0
    Call Tm1637_ack
    'zweite Stelle
    Call Tm1637_wrbyte(ceinerT2)                                   'Digit 2; showing:0
    Call Tm1637_ack
    'dritte Stelle
    Call Tm1637_wrbyte(&B01100011)                                   'Digit 3; showing:0
    Call Tm1637_ack ' Gosub
    'vierte Stelle
    Call Tm1637_wrbyte(&B00111001)                                   'Digit 4; showing:8
    Call Tm1637_ack
    Call Tm1637_stop
End IF

Loop


Sub Einzelzeit

'Zehner Stunden
If _hour <10 or _hour = 20 then Zehnerh = 0
if _hour =>10 and _hour <20 then Zehnerh = 1
if _hour >=20 then Zehnerh = 2

'Einer Stunden
If _hour <10 then einerh = _hour
if _hour =>10 and _hour <20 then
Einerh = _hour - 10
End if
if _hour >20 then
einerh = _hour - 20
End if
if _hour = 20 or _hour = 10   then Einerh = 0
Einerhpunkt = Einerh + 10
'sekunden in 1Takt schalten dann immer auf einerhpunkt und Einerh umschalten

'Zehner Minuten
if _Min <10 then Zehnermin = 0
if _Min =>10 and _Min <20 then Zehnermin = 1
if _Min =>20 and _Min <30 then Zehnermin = 2
if _Min =>30 and _Min <40 then Zehnermin = 3
if _Min =>40 and _Min <50 then Zehnermin = 4
if _Min =>50 then Zehnermin = 5

'einer Minuten
if _min <10 then einermin = _min
if _min >=10 and _min <20 then
einermin = _min - 10
end if
if _min >=20 and _min <30 then
einermin = _min - 20
end if
if _min >=30 and _min <40 then
einermin = _min - 30
end if
if _min >=40 and _min <50 then
einermin = _min - 40
end if
if _min >=50 then
einermin = _min - 50
end if

End sub Einzelzeit


Sub Tempmessung
'Belegung von Pins zu einen von Links nach Rechts Flach oben
'1 = GND
'2 = Signal
'3 = VCC (5V)

 '  -  -  -
 '  1  2  3
 '   \ _ /

If Takt <> Takt_alt Then
Takt_alt = Takt
End If
       ' cli
       ' Stop timer2                                       ' Wird bei ADC nutzung benötige
       1wverify Ds1820id(1)                                       'Sensor aus China
       1wwrite Auslesen
       Sc(1) = 1wread(9)
      ' Start Timer2                                        ' Wird bei ADC nutzung benötige
       T1 = Makeint(sc(1) , Sc(2))
        If Sc(9) = Crc8(sc(1) , 8) Then
        Dgc = Decigrades18b20(sc(9))
        End If

            If dgc < 10 Then zehnT1 = 0
            If dgc >= 10 and dgc <=19 then ZehnT1 = 1
            If dgc >= 20 and dgc <=29 then ZehnT1 = 2
            If dgc >= 30 and dgc <=39 then ZehnT1 = 3
            If dgc >= 40 and dgc <=49 then ZehnT1 = 4

            'Einer Grad T1
            If dgc <10 then einerT1 = dgc
            If dgc >= 10 and dgc <20 then
            einerT1 = dgc - 10
            end if

            If dgc >=20 and dgc <30 then
            einerT1 = dgc - 20
            end if

            If dgc >=30 and dgc <40 then
            einerT1 = dgc - 30
            end if

            If dgc >=40 and dgc <50 then
            einerT1 = dgc - 40
            end if

       'Stop timer2                                         ' Wird bei ADC nutzung benötige
1wverify Ds1820id(9)                                       'Sensor aus China
       1wwrite Auslesen
       Sc(1) = 1wread(9)
      ' Start Timer2                                        ' Wird bei ADC nutzung benötige
       T2 = Makeint(sc(1) , Sc(2))
        If Sc(9) = Crc8(sc(1) , 8) Then
        Dgc = Decigrades18b20(sc(9))
        End If

         If dgc < 10 Then zehnT2 = 0
         If Dgc >= 10 and Dgc <=19 then ZehnT2 = 1
         If Dgc >= 20 and Dgc <=29 then ZehnT2 = 2
         If Dgc >= 30 and Dgc <=39 then ZehnT2 = 3
         If Dgc >= 40 and Dgc <=49 then ZehnT2 = 4

         'Einer Grad T2
         If Dgc <10 then einerT2 = Dgc
         If Dgc >= 10 and Dgc <20 then
         einerT2 = Dgc - 10
         end if

         If Dgc >=20 and Dgc <30 then
         einerT2 = Dgc - 20
         end if

         If Dgc >=30 and Dgc <40 then
         einerT2 = Dgc - 30
         end if

         If Dgc >=40 and Dgc <50 then
         einerT2 = Dgc - 40
         end if

   Restore Sensor_ids

     For I = 1 To 17
     Read Ds1820id(i)
     Next I
     1wreset
     1wwrite Skip_rom
     1wwrite Messen

End Sub TEMPMESSUNG

'End
Sub Tm1637_start                                               '1637 start transmission
   Set Clk
   Set Dio_out
   Waitus 2
   Reset Dio_out
'Return
End Sub
Sub Tm1637_ack                                                 '1637 responses transmission
   Reset Clk
   Waitus 5                                                 'After the eighth clock falling edge delay 5us, start determination ACK signal
   Reset Dio_set
   Bitwait Dio_in , Reset
   Set Clk
   Waitus 2
   Reset Clk
   Set Dio_set
End  SUB
'Return
Sub Tm1637_stop                                                '1637 Stop transmission
   Reset Clk
   Waitus 2
   Reset Dio_out
   Waitus 2
   Set Clk
   Waitus 2
   Set Dio_out
End Sub
'Return
Sub Tm1637_wrbyte                        'Write byte variable passed by the call (Bajt)
   For Temp = 0 To 7                                        'send bit, LSB first
      Reset Clk
       Dio_out = Bajt.temp
      Waitus 3
      Set Clk
      Waitus 3
   Next Temp
End Sub

'Formal für China Sensoren ( DS18B20 )
Function Decigrades18b20(byval Sc(9) As Byte)
 Decigrades18b20 = 0
 Decigrades18b20 = Makeint(sc(1) , Sc(2))
 Decigrades18b20 = Decigrades18b20 / 16
End Function

Sectic:
Takt = _sec
Punktzeit = Punktzeit + 1
Return

'Tempsensoren
Sensor_ids:
Data &H28 , &HA0 , &H29 , &H34 , &H05 , &H00 , &H00 , &H3A  'Innen Sensor T1
Data &H28 , &HDE , &H06 , &H34 , &H05 , &H00 , &H00 , &H26  'Ausen Sensor T2


Ziffern_pattern:                                            'Daten zur Segmentansteuerung.
Data &B00111111  '0                      
Data &B00000110  '1                        
Data &B01011011  '2                     
Data &B01001111  '3                        
Data &B01100110  '4                        
Data &B01101101  '5                        
Data &B01111101  '6                        
Data &B00000111  '7                      
Data &B01111111  '8                         
Data &B01101111  '9                     

Data &B10111111  '0: 10
Data &B10000110  '1: 11
Data &B11011011  '2: 12
Data &B11001111  '3: 13
Data &B11100110  '4: 14
Data &B11101101  '5: 15
Data &B11111101  '6: 16
Data &B10000111  '7: 17
Data &B11111111  '8: 18
Data &B11101111  '9: 19
Data &B01100011   '°  20
Data &B01110111   'A  21
Data &B00111001   'C  22
Data &B00111000   'L  23
Data &B01110110   'H  24
Data &B00000000   'aus 23




habe halt irgenwie bei der Adressierung der der Teile ein Problem denk ich aber für das Display habe ich halt keine Adresse raus bekommen weder im netz noch lässt sich eine auslesen. Da denke ich wird schon das ganze sein oder habt ihr da eine andere Idee.

Habe zwar schon ein Paar Sachen programmiert aber bin trotzdem noch ein blutiger Anfänger.

Würde mich über Tipps freuen
 
Zuletzt bearbeitet:

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.363
61
48
Marwitz
Sprachen
BascomAVR, Assembler
Mal etwas sortieren:
  • DS18B20 - das sind digitale Temperatursensoren, mit denen über ein 1wire-Interface kommuniziert werden kann. Jeder 1wire-Teilnehmer (es gibt nicht nur Temperatursensoren, sondern auch Eeproms oder RTCs) verfügt über eine einzigartige ID, es können also mehrere/viele am "Bus" hängen. 1wire wird von keinem (mir bekannten) AVR in Hardware unterstützt, müßte also in Software implementiert werden. Bascom bietet in seiner Kernbibliothek bereits eine recht gut funktionierende Unterstützung der Temperatursensoren.
  • DS1307 - RTC, mit der über I²C kommuniziert werden kann. Zeit- und Kalenderdaten liegen als (gepackte) Binary Coded Digits in der RTC vor. Außerdem kann ein Ausgang mit diversen diskreten Frequenzen (aus der RTC selbst abgeleitet) angesteuert werden (32,786kHz..1Hz). I²C (als Master) wird von vielen ATmega in Hardware unterstützt (bei den konventionellen ATtiny ist mir nur der ATtiny48/88 bekannt; die neueren X-Core-Tinies können das auch). I²C kann mit einigen Klimmzügen auch durch ein eventuell vorhandenes USI unterstützt werden (haben viele Tinies), ansonsten natürlich auch in Software implementiert werden.
  • TM1637 - das scheint quasi ein Portexpander zu sein. Mittels Multiplexing können 6x8 LEDs (also 48) angesteuert werden, bzw sechs Siebensegment-Digits mit Dezimalpunkt, und 2x8 Taster gelesen werden. Kommuniziert kann wird mit dem IC quasi über I²C, ABER mit der Einschränkung, daß keine Adressprüfung vorgenommen wird. Folglich muß der IC also immer als einziger Teilnehmer am Bus hängen.
Im ersten Codeblock wird außer der RTC ein Character-LCD (über 4-Bit-Parallelbus+Steuerleitungen) verwendet.
Timer0 steuert die Hintergrundbeleuchtung mit PWM.
Es wird eine Soft-Clock konfiguriert, wodurch im Hintergrund (unter anderen) die Variablen _sec _min und _hour dimensioniert werden, und einen String, der die Zeit repräsentiert.
In der Hauptprogramm-Schleife wird nun ununterbrochen die RTC ausgelesen, und das Resultat auf das LCD geschrieben.
Die Konfiguration der Softclock initialisiert meiner Meinung nach so aber auch "einen asynchronen Timer", beim verwendeten Mega32 wahrscheinlich Timer2. Dieser sollte mit einem 32,786kHz-Quarz 'ne quarzpräzise Zeitbasis bereitstellen, und selbst das Uhrwerk antreiben (also eben die im Hintergrund angelegten Variablen). Ist ein entsprechender Quarz nicht angeschlossen, steht der Timer, und damit die ganze Uhr.
Was hast Du also eigentlich programmiert? 'Ne Uhr die steht, aber dafür schaust Du ständig auf die RTC, und stellst die Uhr nach.

Soweit verstanden?

Auf die unnötige Initialisierung und Verwendung des asynchronen Timers kann verzichtet werden - Bascom Hilfe: Config Clock = user.

Insbesondere findest Du dort auch einen Hinweis/Beispiel im Zusammenhang mit einer DS1307.
Meiner Meinung nach entspräche dies etwa Deinem Code, nur daß eben der Timer nicht verwendet wird. Um kontinuierlich 'ne Zeit auf dem Display zu sehen, muß also ununterbrochen die RTC ausgelesen werden.

Jetzt hatte ich ja oben bereits angedeutet, daß die RTC einen Ausgang besitzt, auf dem sie einen Takt (mit der Präzision ihres Quarzes) ausgeben kann. Dieser könnte zum Beispiel auch auf 1Hz gestellt werden, und im AVR einen Interrupt triggern, an den Du dann das Uhrwerk koppelst.
Bei der hier verwendeten Softclock also _sec, _min usw weiterticken läßt.
Am Ende willst Du aber vielleicht gar keinen ASCII-String (für das Character-Display) oder Dezimalzahlen (für irgendwelche Rechnereien) sondern einzelne Ziffern für Deine Siebensegmente, und das sind die Binary Coded Digits, die die RTC liefert. Dann wäre es vielleicht sinniger, auf die Bascom-Softclock ganz zu verzichten, und von den BCDs der RTC gleich auf die darzustellenden Muster der Siebensegmente zu gehen (dazu hast Du ja bereits die "Ziffernpattern")

Grundsätzlich kannst Du entweder (weiterhin) ununterbrochen die RTC auslesen, und die BCDs dann aufbereitet auf die Segmentanzeige ausgeben lassen (was natürlich auf dem I²C 'ne erhebliche Buslast bedeutet, auf der noch nicht geklärten Displayausgabe ebenso).
Oder Du strickst Dir selbst ein Uhrwerk aus Sekunden-einer, Sekunden-zehner, Minuten-einer, Minuten-zehner, Stunden-einer und Stunden-zehner zusammen, welches nur einmal pro Sekunde inkrementiert wird (ausgelöst durch einen IRQ, den die RTC mit ihrem Ausgang auslöst), und auch nur dann irgendwas (neues) aufs Display zaubern muß.
Beim Programmstart wird einmalig die RTC gelesen, und das Uhrwerk synchronisiert - danach liefert die RTC nur noch den Sekundentakt.

Oder wie soll das alles am Ende verbunden werden?

für das Display habe ich halt keine Adresse raus bekommen weder im netz noch lässt sich eine auslesen
Der TM1637? Der hat, wie bereits angedeutet gar keine Adresse. Zitat aus dem Datenblatt:
Interface interpretation
Microprocessor data realize the communication with TM1637 by means of two–wire bus interface (Note: The communication method is not equal to 12C bus protocol totally because there is no slave address). When data is input, DIO signal should not change for high level CLK and DIO signal should change for low level CLK signal. When CLK is a high level and DIO changes from high to low level, data input starts. When CLK is a high level and DIO changes from low level to high level, data input Ends. TM1637 data transfer carries with answering signal ACK. For a right data transfer, an answering signal ACK is generated inside the chip to lower the DIO pin at the failing edge of the 8th clock. DIO interface wire is released at the end of the 9th Clock.
Der ist quasi nach der Startcondition sofort "adressiert" - dummerweise kann dadurch kein anderes Device am Bus hängen, erst recht kein weiterer TM1637.

Grundsätzlich hätte man natürlich vorher besser zueinander passende ICs nehmen können, insbesondere bezüglich dieses siebensegment-ICs.

Aber natürlich sollte sich das so auch in Software umgehen lassen...
 

maikgen

Mitglied
24 Mrz 2010
45
0
6
Sprachen
Erstmal Danke für die Antwort.

Das klingt schon mal gut.
Also wenn ich das jetzt richtig verstehe erzeuge ich mir über Timer1 z.b welchen ich ja noch nicht benutze eine Uhr mit Hilfe eines Uhrenquarz. Diese Lese ich beim Starten kurz aus und lasse sie dann weiter zählen soweit werde ich es hinbekommen. Dann lasse ich die RTC im stillen laufen. bis zum nächsten Start.

Wenn das gemacht ist starte ich dem TM1637 und lasse mir die Zeit anzeigen.

So ganz dumm und hoffe einfach und verständlich geschrieben.

Oder ich besorge mir einfach ein anderes Display da hätte ich an ein HT16k33 gedacht weil ich da die Adressen gefunden habe.
Aber ich glaube ich versuche es erstmal mit dem Timer einem Uhrenquarz habe ich irgendwo noch rumliegen. Mir kommt es ja auch nicht auf die Minute an wenn ich mal zwei Stunden fahre und da geht die Uhr mal 2 oder 3 Minuten vor oder nach das ist Wurst.
Es geht darum gerade wenn ich auf Arbeit fahre und viel Verkehr ist kann man es schlecht einschätzen wie spät ist es muss ich mich ranhalten oder habe ich Zeit. Es reicht mir auch wenn nur die Stunden und Minuten angezeigt werden.

Beim Starten holt er sich ja eh die aktuelle Zeit von der RTC
 
Zuletzt bearbeitet:

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.363
61
48
Marwitz
Sprachen
BascomAVR, Assembler
Also wenn ich das jetzt richtig verstehe erzeuge ich mir über Timer1 z.b welchen ich ja noch nicht benutze eine Uhr mit Hilfe eines Uhrenquarz.
Jain, bei Deinem Mega32 unterstützt nur Timer2 diesen asynchronen Betriebsmodus (d.h. er wird an den Takt des Uhrenquarzes gekoppelt, und läuft unabhängig vom restlichen Systemtakt - und eben mit der Präzision des Uhrenquarzes und nicht der ggf ungenaueren des Systemtaktes - asynchron halt).

Aber Du brauchst den Timer dazu gar nicht. Wenn Du (wie im ersten Beispiel ständig die RTC ausliest nicht, und wenn Du das nicht willst, liefert Dir die RTC ja entsprechend eingestellt auch 'nen Sekundentakt.

Also nach dem Start erstmal den Sekundentakt in der RTC aktivieren, dann die RTC auslesen und das Uhrwerk stellen.
In den Sekunden-Interrupts läßt Du Deine Uhr ein weiterticken, und aktualisierst die Anzeige.

TM1637 und auch der Holtek sind ja nur die Treiber-ICs - was ist da dann eigentlich drauf? Siebensegmente? Dotmatritzen?

Für Siebensegmentanzeigen werden auch oft PCF8574 oder ähnlich eingesetzt.
 

fredred

Mitglied
1 Okt 2015
72
2
7
Hallo Maikgen,

Lotada hat schon die wichtigsten Fragen beantwortet.
Für mich bleibt aber erst mal die Frage warum RTC 1307 wenn du DCF-77 hast.
Finde auch den LED- Drive Control TM 1637 nicht die beste Wahl wenn der I2C genutzt werden soll.
Wie schon geschrieben die Tempetatursensoren DS 1820x haben nichts mit I2C – Bus zu tun.
Nun erlaube ich mir mal mein Projekt „Kalenderuhr“ in Anhang zu legen. Ist ja auch mit 7 Segment Display ( aber Treiber ist ein Max 7219), RTC1307 und Zusätzlich mit ein LCD Display 16x2. So ein LCD - Display hat auch den Vorteil der besseren Ansicht wenn du gleichzeitig Zeit und Temperatur anzeigen möchtest.
Kleiner Temperatur-Code hier. Ist schon für mehrere Sensoren gedacht. Kannst viele einfach parallel an einen Pin anschließen zum weiterverarbeiten wird die Adresse vorab ermittelt.


CodeBox BascomAVR
'****************** Test-Platine ************************
'* ist ein Testmodul für Digital Temperatur-Sensoren    *
'* [DS18x20] DS18S20 ist ein 9 Bit Family Adr &H10      *
'* und DSB20 ein 12 Bit Family Adr &H28                 *
'* somit große Unterschiede bei der "Empfindlichkeit"   *
'* Das lesen der Bit's ist somit auch Unterschiedlich.  *
'********************************************************


$regfile "m32def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 40
$baud = 19200

'### LCD Verbindungen mit Controller###
Lcd_db4 Alias Portd.5
Lcd_db5 Alias Portd.4
Lcd_db6 Alias Portd.3
Lcd_db7 Alias Portd.2
Lcd_e Alias Portd.6
Lcd_rs Alias Portd.7

Config Lcdpin = Pin , Db4 = Lcd_db4 , Db5 = Lcd_db5 , Db6 = Lcd_db6 , Db7 = Lcd_db7 , E = Lcd_e , Rs = Lcd_rs

Config Lcd = 16 * 2                                         'dies ist die Kennung für Lib Lcdpin
Cursor Off Noblink                                          'Aus und nicht blinken
Lcdinit
Waitms 100

'für Test die am Port B.0 angeschlossenen Temperatursensoren
Declare Sub Ds1820_alleseriennummern()

'Temperatursensor Anschluß an Portpin B.0
Dim 1wtemp_adresse_1(8) As Byte                             ' Adresse des Temperatursensors 1
Dim 1wtemp_adresse_2(8) As Byte                             ' Adresse des Temperatursensors 2
Dim Temp_bytes(9) As Byte
Dim Tempdif As Integer
Dim Tempdif1 As Integer                                     'Variable zur Temp. Berechnung DeziGrad
Dim Temp1 As Single
Dim Temp2 As Single

'Format für Single zwei Nachkommastellen
Config Single = Scientific , Digits = 1                     'wenn die 2 benötigt im Empf. + Zentrale anpassen.

'Temperatursensoren DS 18S20 an PortB.0 (Bascom Unterprogramm einbinden)
Config 1wire = Portb.0                                      'Temperatursensor 1und2
 Portb.0 = 1                                                'Port auf H schalten

'------Temperatursensor erkennen-------
'testet die am Portpin B.0 angeschlossenen Temperatursensoren
Call Ds1820_alleseriennummern()

1wtemp_adresse_1(1) = 1wsearchfirst()                       'ist der erste gefundene Sensor
1wtemp_adresse_2(1) = 1wsearchnext()                        'suche nächsten
'1wtemp_adresse_3(1) = 1wsearchnext()                        'wenn noch mehr erweitern

Cls


Do

'Temperatursensoren Daten einlesen
  Gosub Temperaturmessung
  Print "  Temp1  " ; Temp1
  Print "  Temp2  " ; Temp2
'nun was anzeigen
   Locate 1 , 1                                             'Cursor auf 1 Zeile, 1 Spalte
    Lcd "  Temp1  " ; Temp1
   Locate 2 , 1                                             'Cursor auf 2 Zeile, 1 Spalte
    Lcd "  Temp2  " ; Temp2

Loop
    End


Temperaturmessung:
   ' bei allen Sensoren den Messvorgang starten
   1wreset
   1wwrite &HCC                                             ' SKIP ROM, alle Sensoren ansprechen
   1wwrite &H44                                             ' CONVERT T, Temperatur messen
 'Zeit zum Messen geben
   Waitms 50

'===== erster Temp.-Sensor ist ein S Typ=====

   1wreset
   1wverify 1wtemp_adresse_1(1)
   1wwrite &HBE                                             ' Read Scratchpad, Temperatur auslesen
'Zeit zum Messen geben
   Waitms 100
    Temp_bytes(1) = 1wread(8)
    Tempdif = Makeint(temp_bytes(1) , Temp_bytes(2))        'erstes und 2 Byte(LSB+MSB) zusammenfügen

    Tempdif = Tempdif * 50
    Tempdif = Tempdif - 25.6
    Tempdif1 = Temp_bytes(8) - Temp_bytes(7)
    Tempdif1 = Tempdif1 * 100
    Tempdif1 = Tempdif1 / Temp_bytes(8)
    Tempdif = Tempdif + Tempdif1
    Temp1 = Tempdif / 100

'(
'===== zweiter Temp.-Sensor wenn auch ein S Typ  =====
   ' Anfrage senden
   1wreset
   1wverify 1wtemp_adresse_2(1)
   1wwrite &HBE                                             ' Read Scratchpad, Temperatur auslesen
    Temp_bytes(1) = 1wread(8)
    Tempdif = Makeint(temp_bytes(1) , Temp_bytes(2))        'erstes und 2 Byte(LSB+MSB) zusammenfügen.

    Tempdif = Tempdif * 50
    Tempdif = Tempdif - 25.6
    Tempdif1 = Temp_bytes(8) - Temp_bytes(7)
    Tempdif1 = Tempdif1 * 100
    Tempdif1 = Tempdif1 / Temp_bytes(8)
    Tempdif = Tempdif + Tempdif1
    Temp2 = Tempdif / 100
 'Zeit zum Messen geben
   Waitms 10
')

 '===== erster Temp.-Sensor wenn es ein B Typ ist =====
   ' Anfrage senden
   1wreset
   1wverify 1wtemp_adresse_2(1)
   1wwrite &HBE                                             ' Read Scratchpad, Temperatur auslesen
 'Zeit zum Messen geben
    Waitms 100

    Temp_bytes(1) = 1wread(8)
    Tempdif = Makeint(temp_bytes(1) , Temp_bytes(2))        'erstes und 2 Byte(LSB+MSB) zusammenfügen.
    Tempdif = Tempdif / 8                                   'hier der Unterschied
    Tempdif = Tempdif * 50
    Tempdif = Tempdif - 25.5
    Tempdif1 = Temp_bytes(8) - Temp_bytes(7)
    Tempdif1 = Tempdif1 * 100
    Tempdif1 = Tempdif1 / Temp_bytes(8)
    Tempdif = Tempdif + Tempdif1
    Temp2 = Tempdif / 100

 Return


'-------------------------------------------------------------------------------

'############# nach Neustart Temperatursensor Test ###############

'wird dieser Test Erfolgreich beendet wird die "Messung" oben in den Variablen
'geschrieben [1wtemp_adresse_1(1)] ist der erste Sensor und
'und [1wtemp_adresse_2(1)] ist der zweite usw.

'Gibt die Seriennummer aller Sensoren des Bus über COM(TTL) aus.
'wenn Hardware-Fehler wird dieser angezeigt.

Sub Ds1820_alleseriennummern()
Local Crc As Byte
Local I As Integer
Local Anzahl As Integer
Dim Adresse(8) As Byte
Adresse(1) = 1wsearchfirst()                                'prüft den ersten Teilnehmer am Bus
If Err = 0 Then                                             'Wenn err, dann gibt es keinen Sensor

'ist nur für Info die Hex-Adresse ist "Name" mit dieser Kenntnis
'kannst Du mit [1wwrite &H55 und 1wwrite Sensor1_id("Name") , 8
'jeden einzeln ansprechen. Mach bei mehreren Sensoren Sinn.

Print "sind Hex-Adresse der Ds1820"

'ab hier prüfen
Do
Crc = Crc8(adresse(1) , 7)
 If Crc <> Adresse(8) Then Print "Daten fehlerhaft gelesen (CRC-Fehler)!"
    For I = 1 To 8
      Print Hex(adresse(i)) ;
      Print " ";
    Next
     Print

  Adresse(1) = 1wsearchnext()                               'nächste suchen
Loop Until Err = 1
 End If
'Print
 Anzahl = 1wirecount()                                      'Anzahl der Sensoren
  Print "Anzahl der Sensoren am Bus: " ; Anzahl
  Print
  Print "Test abgeschlossen"
  Print "Hauptprogramm wird gestartet"
  Print
   Wait 5
End Sub




Dim Sngeeprom As Single                                     'Single to/from EEPROM
Dim Bytsngeep(4) As Byte At Sngeeprom Overlay
Dim Wrdaddr As Word                                         'EEPROM address
Dim Byttmp0 As Byte                                         'Temporary byte variable
Dim Sngtmp0 As Single                                       'Temporary single variable

'Declare subs
Declare Sub Eepromwritesng(byref Sngsingle As Single)
Declare Sub Eepromreadsng(byref Sngsingle As Single)

Wrdaddr = 11                                                'EEPROM start address
Sngtmp0 = 123.456                                           'Single to be stored in EEPROM
Call Eepromwritesng(sngtmp0)                                'Store sngTmp0 to EEPROM

Wrdaddr = 11
Call Eepromreadsng(sngtmp0)                                 'Retrieve sngTmp0 from EEPROM

'==============================================================================
Sub Eepromwritesng(byref Sngsingle As Single)
'Decode sngSingle to 4 bytes of bytSngEEP for writing to EEPROM
'Input sngSingle is set to sngEEPROM, overlayed with bytSngEEP(i), i=1...4
'The 4 bytes bytSngEEP(i)are written to EEPROM
'Input:  sngSingle to be decoded & written to EEPROM
'        wrdAddr first EEPROM address

   Sngeeprom = Sngsingle                                    'Set input
   For Byttmp0 = 1 To 4
      Writeeeprom Bytsngeep(byttmp0) , Wrdaddr
      Incr Wrdaddr
   Next Byttmp0
End Sub

'==============================================================================
Sub Eepromreadsng(byref Sngsingle As Single)
'Encode 4 bytes read from EEPROM to sngSingle
'The 4 bytes are read to bytSngEEP(i), i=1...4
'bytSngEEP is overlayed @ sngEEPROM
'sngEEPROM is set to output sngSingle
'Input:  wrdAddr first EEPROM address
'Output: sngSingle encoded to single variable read from EEPROM

   For Byttmp0 = 1 To 4
      Readeeprom Bytsngeep(byttmp0) , Wrdaddr
      Incr Wrdaddr
   Next Byttmp0
   Sngsingle = Sngeeprom                                    'Set output
End Sub





Erstmal Danke für die Antwort.

Das klingt schon mal gut.
Also wenn ich das jetzt richtig verstehe erzeuge ich mir über Timer1 z.b welchen ich ja noch nicht benutze eine Uhr mit Hilfe eines Uhrenquarz. Diese Lese ich beim Starten kurz aus und lasse sie dann weiter zählen soweit werde ich es hinbekommen. Dann lasse ich die RTC im stillen laufen. bis zum nächsten Start.

Wenn das gemacht ist starte ich dem TM1637 und lasse mir die Zeit anzeigen.

So ganz dumm und hoffe einfach und verständlich geschrieben.

Oder ich besorge mir einfach ein anderes Display da hätte ich an ein HT16k33 gedacht weil ich da die Adressen gefunden habe.
Aber ich glaube ich versuche es erstmal mit dem Timer einem Uhrenquarz habe ich irgendwo noch rumliegen. Mir kommt es ja auch nicht auf die Minute an wenn ich mal zwei Stunden fahre und da geht die Uhr mal 2 oder 3 Minuten vor oder nach das ist Wurst.
Es geht darum gerade wenn ich auf Arbeit fahre und viel Verkehr ist kann man es schlecht einschätzen wie spät ist es muss ich mich ranhalten oder habe ich Zeit. Es reicht mir auch wenn nur die Stunden und Minuten angezeigt werden.

Beim Starten holt er sich ja eh die aktuelle Zeit von der RTC
1. Warum soll es ein Display mit seriellem Datenaustausch sein.
2. Ein RTC benötigt kein DCF für Zeiteinstellung. In meinem Beispiel siehst du Taster reichen um vielleicht 2 mal im Jahr die Zeit zu stellen(Zeitumstellung), wenn wie du schreibt, bis zu 10s Differenz im Jahr noch genau genug sind.

Sind alles nur allgemeine Anregungen.

Wenn Fragen dann fragen.
Gruß
PS.
An alle hier im Forum ein gesundes erfolgreiches 2020.
 

Anhänge

maikgen

Mitglied
24 Mrz 2010
45
0
6
Sprachen
Hallo Fredred

Die DCF-Uhr hat nur einmal die RTC gestellt das reicht mir die sollte ja jetzt relativ gut laufen, und einmal im Jahr / Winter kann man die auch mal ausbauen und neu stellen, wenn sie arg weit weg ist. ich bin mir auch nicht sicher ob die DCF Uhr im Moped die Uhrzeit findet und was mich am meisten nervt das es machmal lange dauert bis er die Zeit hat. ich will ja gleich wissen wie Spät es ist wenn ich losfahre.
Taster wollte ich keine verbauen weil das im Moped schlecht ist und irgendwer daran rumdrückt und und und. Das normale LCD Display (16x4) hängt jetzt erstmal nur zu Testzwecken mit dran um überhaupt was angezeigt zubekommen. Das fällt definitiv weg im finalen Programm weg.
Serial wollte ich machen weil ich dann am Ende aus Platz gründen nicht soviele kabel haben wollte was ja im Idealfall bie I²C 4, plus Wire1 nochmal 3 bzw nur 1 draht ist (5V und GND fasse ich bei I²C ab). Das 7segment display sollte es auch sein das es schön "klein" ist und ich es günstig verbauen kann. Hatte auch mal mit einem 1x4 LCD geschaut aber da brauch ich wieder zuviel Kabelzeugs.


Edit
Hab das jetzt so das er mit jede Minuten die Zeit von der RTC ausließt ist dann die Frage ob ich das jede Minute mache oder ob ich das auf alle 5 Minuten oder alle 15 Minuten mache das reicht mir auch dicke
 
Zuletzt bearbeitet:

fredred

Mitglied
1 Okt 2015
72
2
7
Dein Verwendungszweck hättest Du mit angeben sollen.
Eine Lösung mit TFT LCD Touch und SPI Schnittstelle hätte ich.
Naja, da ich nicht weiß ob ein ca. 46 x 25 mm Farbdisplay zu groß ist oder die max 6 Kabel zu viel sind oder die wetterfeste Touchbedienung nicht gewünscht ist las ich es mal, weitere Vorschläge zu machen.
Ist halt immer mein Problem bei einem „finalen“ Projekt zu helfen ohne es zu kennen.
Habe auch noch ein LCD – Display 4x 8 mm aber nur Mode 4 = 6 Kabelanschluss. Was soll es.
Bitte um Entschuldigung für mein Kommentar.
Mit freundlichen Grüßen
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.363
61
48
Marwitz
Sprachen
BascomAVR, Assembler
Die DCF-Uhr hat nur einmal die RTC gestellt das reicht mir die sollte ja jetzt relativ gut laufen, und einmal im Jahr / Winter kann man die auch mal ausbauen und neu stellen,
Hatte ich auch so verstanden. Als Alternative zu RTC und/oder DCF77 gäbe es noch GPS. Würde neben der Zeit auch Tempo + Kurs liefern (von den reinen Koordinaten wirst Du nicht viel haben ... obwohl … ich hab hier auch noch ein ähnliches Projekt auf Eis, wo die Position Google-Maps-kompatibel geloggt werden soll (Routentracker, allerdings fürs Kajak, also … etwas langsamer;))
Serial wollte ich machen weil ich dann am Ende aus Platz gründen nicht soviele kabel haben wollte was ja im Idealfall bie I²C 4, plus Wire1 nochmal 3 bzw nur 1 draht ist (5V und GND fasse ich bei I²C ab). Das 7segment display sollte es auch sein das es schön "klein" ist und ich es günstig verbauen kann. Hatte auch mal mit einem 1x4 LCD geschaut aber da brauch ich wieder zuviel Kabelzeugs.
???
Display + Zeit-Quelle (RTC/DCF/GPS/Whatever) + Controller auf dieselbe Platine (Beidseitig bzw die Schaltung unters Display) dann hast Du nur Strippen für die Stromversorgung. Und natürlich die Temperatursensoren, aber die sollen vielleicht eh bestimmte Temps messen...
Die 1wire-Sensoren kannst Du auch Parasite-Powered betreiben, dann benötigen die nur die Datenleitung und Gnd. Inwiefern Gnd beim Mopped über den Rahmen etc gelegt werden kann, weiß ich nicht - dann wärst Du bei einer Leitung... 1wire eben.

Beim Display wären bezüglich der Ablesbarkeit auch eInk-Displays (oder wie die jetzt auch immer heißen) 'ne Überlegung wert - vielleicht auch OLEDs

Nochmal 'ne fixe Idee bezüglich RTC usw: Man könnte eben doch 'ne Softclock im Controller nutzen, also 'n 32,786kHz Uhrenquarz an einem asynchronen Timer. Insbesondere, wenn die Uhr keine Sekunden braucht, kann der Controller selbst rumidlen; der Timer tickt durch den Uhrenquarz und weckt den Controller nur noch einmal die Minute oder so...
Quasi ist der Controller dann 'ne RTC mit Display und Tempsensoren drann...
Könnte man auch batteriegepuffert realisieren (bei erkannter Stromversorgung werden Temperaturen, Zeit usw auf dem Display dargestellt, nimmst Du den Strom weg (Zündung aus oder so), werden Sensoren und Display abgeschaltet, und der Controller realisiert nur noch die RTC-Funktion, und das möglichst sparsam.)
Sinnig wäre dann außerdem 'ne Möglichkeit, den Controller mittels DCF/Internetzeit/whatever zu stellen...
Empfehlenswert wäre dann wohl ein picoPower-Tiny mit asynchronem Timer. Irgendwie habe ich diesen Punkt in meiner Tiny-Übersicht bisher vernachlässigt... hmm...

Möglicherweise reicht es auch, den Controller direkt mit dem Uhrenquarz zu Takten, wäre ja nicht wirklich viel zu rechnen(*). Der ATtiny441/841 besitzt zB einen entsprechenden Low Frequenzy Crystal Oszillator.


(*) Was mich an Freds Code etwas … stört, sind die unnötigen Multiplikationen und Divisionen - und sogar die Verwendung von Fließkommavariablen.
Der DS18B20 digitalisiert immer auf der Basis von sechzehntel Kelvin (wobei je nach Wandlungsgeschwindigkeit (bzw "Auflösung") die letzten Bits zu verwerfen sind.

Der DS18S20 sollte das quasi identisch machen, legt das Ergebnis allerdings so ab, daß nur halbkelvin-basiert ausgelesen werden kann, und eine höhere Genauigkeit rechnerisch aus weiteren Registern rekonstruiert werden kann.
Warum so kompliziert?
Weil der DS18S20 den noch älteren DS1820 ersetzen sollte, und das eben ohne daß Softwareanpassungen nötig sind.
Deswegen besitzen beide auch dieselbe … äh … Family-ID (?)

Beim ...S20 ist allerdings Count_per_C (eines der Scratchpad-Register) immer(!!) 16 (0x10), also 'ne schöne Zweierpotenz. Da dieser Wert in der Rekonstruktionsformel ein Teiler ist, muß statt der Division beim ...S20 eben nur noch geschoben werden, die Division als solche entfällt.

Jetzt stellt sich die Frage, ob/warum man bei einem neuen Projekt einen alten, umständlicher auszuwertenden Sensor unterstützen muß.

Das ganze hatten wir übrigens hier "vor kurzem" schonmal durchexerziert, mit dem ...B20 ist die "Rechnung" noch simpler (nur noch schieben).
Als Ergebnis hat man hinterher 'ne vorzeichenbehaftete Ganzzahl (im Sinne des Zweierkomplementes, genau genommen hatte ein Byte Vorkommastellen, ein Byte Nachkommastellen). Die Nachkommastellen in einzelne Ziffern zu zerlegen ist kein Problem, bei den Vorkommastellen ist's etwas komplexer...

Eigentlich wollte ich damals dazu 'ne Bascom-Bibliothek schreiben (wobei die Rechenschritte inklusive CRC bereits während des Empfanges durchexerziert werden) - irgendwie hatte ich wohl keine Zeit dazu...
 

fredred

Mitglied
1 Okt 2015
72
2
7
(*) Was mich an Freds Code etwas … stört, sind die unnötigen Multiplikationen und Divisionen - und sogar die Verwendung von Fließkommavariablen.
Der DS18B20 digitalisiert immer auf der Basis von sechzehntel Kelvin (wobei je nach Wandlungsgeschwindigkeit (bzw "Auflösung") die letzten Bits zu verwerfen sind.

Der DS18S20 sollte das quasi identisch machen, legt das Ergebnis allerdings so ab, daß nur halbkelvin-basiert ausgelesen werden kann, und eine höhere Genauigkeit rechnerisch aus weiteren Registern rekonstruiert werden kann.
Warum so kompliziert?
Weil der DS18S20 den noch älteren DS1820 ersetzen sollte, und das eben ohne daß Softwareanpassungen nötig sind.
Deswegen besitzen beide auch dieselbe … äh … Family-ID (?)

Beim ...S20 ist allerdings Count_per_C (eines der Scratchpad-Register) immer(!!) 16 (0x10), also 'ne schöne Zweierpotenz. Da dieser Wert in der Rekonstruktionsformel ein Teiler ist, muß statt der Division beim ...S20 eben nur noch geschoben werden, die Division als solche entfällt.

Jetzt stellt sich die Frage, ob/warum man bei einem neuen Projekt einen alten, umständlicher auszuwertenden Sensor unterstützen muß.
[/QUOTE]

Gebe dich völlig Recht.
Aber oft ist es so in dieser Programmiersprache, dass eine „komplizierte“ Formel = allgemeinverständliche Berechnung, mehr aussagt und verständlicher ist, als ein Bitschubser Beispiel oder gleich in ASM. Natürlich sind es oft Verschwendungen von Speicher aber wenn man genügend hat macht es auch einwenig Spaß diese zu verballern.
Die Verwendung von Fließkommavariablen macht doch auch Sinn, wenn diese Variablen in ein Projekt auch für weitere Zwecke benötigt werden z.B. für andere Berechnungen oder Anzeigen.
Somit war mein kleiner Codeschnipsel, wie geschrieben nur eine Anregung. Wenn bekannt berücksichtige ich auch die Vorhandene Hardware des Fragenden(wenn Er olle DSxxx in der Bastelkiste hat, warum soll er sich teure moderne kaufen um ans Ziel zu kommen?)
Finde es aber immer Gut, wenn solche Hinweise kommen, dann kommen auch die Fragen und Antworten wie es optimaler zu lösen ist und nur so Funktioniert ein gutes Forum.

Mit freundlichen Grüßen

Fred
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.363
61
48
Marwitz
Sprachen
BascomAVR, Assembler
Natürlich sind es oft Verschwendungen von Speicher
...und Rechenzeit. Natürlich kein Problem, wenn man genug davon hat, aber wenns eng wird heißt es schnell, daß der Controller zu schwach dazu wäre, und das stimmt eben nicht, wenn man Berechnungen nicht unnötig kompliziert durchführen läßt.

Die AVR sind acht-Bit-Controller, sie rechnen halt binär mit acht Bit. Das kann man zu 16, 24, 32 Bit usw kombinieren, aber es sind immer ganze Zahlen. Man kann sich jetzt einfach ein Komma an irgend'ne Stelle Denken, mit Zehnteln/Hundertsteln usw Rechnen, ohne daß wirklich ein Komma existiert.

Die Verwendung von Fließkommavariablen macht doch auch Sinn, wenn diese Variablen in ein Projekt auch für weitere Zwecke benötigt werden z.B. für andere Berechnungen
Sehe ich hier nicht so. Der B-Typ liefert 'n Integer, also 'ne Ganzzahl; der S-Typ letztlich auch - nur beim alten DS1820 wäre so eine ganzzahlige Integerdivision drin, die möglicherweise(!!) Genauigkeit verschenkt - ob das was ausmacht, weiß ich nicht.
Wenn Du Dir die Zahl eben normiert mit Mantisse und Exponent anzeigen lassen willst, ok. Für BCDs oder Dezimalstellen-ASCII wirst Du immer rechnen müssen, und da sind Integer meiner Meinung nach trotzdem einfacher zu handhaben.

Warum trotzdem Fließkomma? Weil jemand Dir das Programmieren da bereits abgenommen hat, und weil Du selbst im Dezimalsystem mit Kommazahlen denkst. Aber der Sensor liefert Ganzzahlen, der AVR verarbeitet Ganzzahlen...

wenn Er olle DSxxx in der Bastelkiste hat, warum soll er sich teure moderne kaufen um ans Ziel zu kommen?
Hmm...
auch die Temperaturen der DS1820b Sensoren
Hatte ich als DS18B20 interpretiert; ferner deuten die Zeilen 359..360 seines 2ten Codeblockes darauf hin.

Der liefert bereits 'ne Integerzahl, wobei ein Bit einem sechzentel Kelvin entspricht.

Jetzt mal ein paar Fragen zu Deinem Programm:
Du liest das Sensor-Scratchpad ja auch in ein Array of Byte aus - warum kopierst Du diese Daten dann nochmal in Deine Rechenvariablen?
Makeint erhält als Parameter ja zwei Byte-Variablen, und kopiert diese einfach in eine Integervariable (als zwei aufeinanderfolgende Byteadressen). Die beiden Bytes des Arrays folgen aber bereits aufeinander, und stehen auch in der richtigen Reihenfolge.
Du mußt also nur dafür sorgen, daß Deine Integervariable (tempdif) auf die erste (bzw die ersten Beiden) Zelle(n) im Scratchpad-Abbild (temp_bytes(1)) zugreift, und das kannst Du mit Overlay.

In den Zeilen 97, 114 und 136 ziehst Du 25,5 bzw 25,6 von einer Ganzzahl ab?? (Also das Ergebnis wird auch wieder 'ner Ganzzahl zugewiesen?)

Du läßt letztlich mit Hundertstel-°C rechnen, ich mit 256steln (was die Rechnung erheblich erleichtert - ich erhalte ein Byte Vorkomma, ein Byte Nachkomma.)

Aber was ist mit der Routine für den B-Typen? Das ist doch quasi dieselbe wie bei den anderen.

Scratchbyte7=tempbytes(8) ist 0x10, was den 16tel Graden entspricht, das paßt - aber bei Byte6=tempbyte(7), welches sonst Count_remain enthält, steht hier nur "reserved" - was wird da empfangen?
 

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