DS1307 "zu Fuß" in Bascom

fofi1

Mitglied
09. Jan. 2010
116
1
18
Sprachen
Hallo,

ich versuche gerade den DS1307 ohne die fertige Bascom lib zum laufen zu kriegen, da ich alle Variablen für Berechnungen brauche (Langzeit-Countdown). Jetzt habe ich gerade ein gewaltiges Problem: Der Ds1307 schmeißt mir nur irrsinnige Werte für die Uhrzeit entgegen. Ich hocke jetzt bestimmt schon 2 Stunden an dem Problem, hab ein Testprogramm (unten) geschrieben und komme einfach ned weiter:stupido3:

Ums gleich vorweg zu sagen: der Code enthält Teile des Codes von www.pirnaer.de . Dieser war am Anfang zum üben gebraucht worden und dann später in das unten gepostete Programm verändert worden. Bis auf manche Ausleseroutinen erkennt man ihn sowieso nicht wieder.

Code:
$regfile = "m168def.dat"
$crystal = 8000000

'Lcd Init
Config Lcd = 40 * 2
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portb.1 , Rs = Portb.2


' Einstellen der I2C Schnittstelle
Config Sda = Portc.4
Config Scl = Portc.5

' Addresse des DS1307
Const Ds1307w = &HD0
Const Ds1307r = &HD1

'Variablen
Dim Sekunde As Byte
Dim Minute As Byte
Dim Stunde As Byte
Dim Wochentag As Byte
Dim Tag As Byte
Dim Monat As Byte
Dim Jahr As Byte
Dim Dummy As Byte

'Lcd bereinigen
Cls
Cursor Off


'Hier beginnt der Zeiteinstellpart!!
'##############################################################
Sekunde = 40
Minute = 59
Stunde = 11

Tag = 12
Monat = 11
Jahr = 10                                                   '2010 geht nicht, da byte. Umgehen?

'Datum stellen
  I2cstart                                                  ' Start
  I2cwbyte Ds1307w                                          ' DS1307 schreiben
  I2cwbyte 4                                                ' DS1307 Adresszeiger auf 4 (Byte 5) stellen
  I2cwbyte Tag                                              ' Tag schreiben
  I2cwbyte Monat                                            ' Monat schreiben
  I2cwbyte Jahr                                             ' Jahr schreiben
  I2cstop
'Uhrzeit stellen
  I2cstart                                                  ' Start
  I2cwbyte Ds1307w                                          ' DS1307 schreiben
  I2cwbyte 0                                                ' DS1307 Adresszeiger auf 0 stellen
  I2cwbyte Sekunde                                          ' Sekunden schreiben
  I2cwbyte Minute                                           ' Minuten schreiben
  I2cwbyte Stunde                                           ' Stunden schreiben
  I2cstop
'#################################################################
'Hier endet der Zeiteinstellpart!



Do
'Auslesen
  I2cstart                                                  ' Start
  I2cwbyte Ds1307w                                          ' DS1307 schreiben
  I2cwbyte 0                                                ' DS1307 Adresszeiger auf 0 stellen


  I2cwbyte Ds1307r                                          ' DS1307 lesen (ab vorher eingestellter Adresse 0)
  I2crbyte Sekunde , Ack                                    ' Sekunden
  I2crbyte Minute , Ack                                     ' Minuten
  I2crbyte Stunde , Ack                                     ' Stunden
  I2crbyte Wochentag , Ack                                  ' Wochentag 
  I2crbyte Tag , Ack                                        ' Tag
  I2crbyte Monat , Ack                                      ' Monat
  I2crbyte Jahr , Nack                                      ' Jahr
  I2cstop

  Sekunde = Makedec(sekunde) : Minute = Makedec(minute) : Stunde = Makedec(stunde)
  Tag = Makedec(tag) : Monat = Makedec(monat) : Jahr = Makedec(jahr)


'Anzeigen
Locate 1 , 1
Lcd Tag ; " " ; Monat ; " " ; Jahr ; " ";
Locate 2 , 1
Lcd Stunde ; " " ; Minute ; " " ; Sekunde ; " ";

Loop

End

Das Lcd zeigt an:
12 11 10 (passt alles)
11 41 28 (warum?????)

Wie kann ich das 24 Stunden-Format einstellen? Ich habe dazu zwar verschiedenes gelesen, aber nichts funktioniert.

Danke schonmal

Mfg,
Flo
 
Hi Flo,

fehlt in der 5. Zeile nach dem "Do" nicht ein "I2cstop"?
Alternativ könnte man auch das folgende "I2cstart" weglassen, wenn ich mich nicht irre (Sam Hawkens).

Schönen Gruss
Markus
 
Hallo,

lt. Datenblatt kann der DS1307 nur 100kHz I²C-Busgeschwindigkeit, und wenn ich die Beispiele zum DS1307 ansehe werden die Werte vor dem Schreiben ins BCD-Format gewandelt.

Gruß
Udo
 
Hallo,

danke,ihr habt beide recht. Ich werde das mal in den nächsten Stunden probieren.

Edit: ES geht! Ihr seid super. TOP! Eine einzige Frage hab ich noch, da ich das nicht im Datenblatt verstehe: Wie kann ich 24Stundenformat einstellen?

Danke:)
 
Moin Flo,

eigentlich ganz simpel:

Bit 6 in Byte 2 stellt 12/24 Stunden um.

Ist es 0, werden 12 Stunden dargestellt und Bit 5 gibt an, ob es sich um "am" oder "pm" handelt. Bit 4 ergibt die höhere Ziffer der Stunden (0 oder 1).

Ist es 1, werden 24 Stunden dargestellt, wobei dann Bit 4+5 die höhere Ziffer der Stunden ergibt (0, 1 oder 2)

Du musst es halt beim Schreiben mit dazupacken und nach dem Lesen rausfiltern.

Schönen Gruss
Markus
 
Danke dir. Jetzt funktioniert alles TOP:adore: . Jetzt ist mir auch die bisschen umständliche Aufzeichnung im Datenblatt klar.

Mfg,
FLo
 
Hi, warum einfach wenns auch umständlich geht.

Gugst Du im Beitrag http://www.avr-praxis.de/forum/showthread.php?t=60 hier im Forum. Da gibt es schon eine fertig implementierte Lösung mit viel Kommentar!

Trotzdem Glückwunsch zur Lösung :party:
Selber gemacht ist immer noch besser als abgeschaut .... der Lerneffekt ist größer!

Grüße und weiter so,
Markus
 
Hi,

danke dir. Ich hab in deinem Code mindestens noch 20 Sachen gefunden, dein Code hat mich grad nebenbei ermutigt ein DCF77 Modul anzusteuern:) . Mit dem Lerneffekt haste zu 100% recht. Ich bin erstaunt, wieviel man aus nem Datenblatt rausquetschen kann;) .

Kleine Frage noch zu dem Thema, weils grad so gut dazupasst: Ich wollte die Zeiten noch zerlegen (für 7 Segmentanzeigen). Dazu müsste ich die Bytes (z.B: Sekunden) in 2 Ziffern aufteilen (z.B: 23 in 2 und 3). Ich habe aber keine Ahnung ob es da einen passenden Befehl gibt. Googeln ohne exakte Begriffe hat leider nix gebracht. Wisst ihr da eine Methode oder einen Befehl um das zu machen? Was wäre eigentlich wenn ich z.B 7 Sekunden in einem Byte habe und dieses dann aufteile. Das sollte ja 0 und 7 ergeben oder?

Boah, ist immer wieder schwer sich in neue Hardware reinzufinden, da die Software dann auch ihre Tücken mit sich bringt:) . Am meisten das 7 Segment Multiplexen zu den RTC Werten birgt so seine Probleme, wenn man es noch nie versucht hat.

Mfg,
Flo
 
Hallo Flo,

Ich bin erstaunt, wieviel man aus nem Datenblatt rausquetschen kann;) .
Datenblätter sind das A+O der Elektronik. Wenn du mit denen klarkommst,
dann hast du schon halb gewonnen ;)

Kleine Frage noch zu dem Thema, weils grad so gut dazupasst: Ich wollte die Zeiten noch zerlegen (für 7 Segmentanzeigen). Dazu müsste ich die Bytes (z.B: Sekunden) in 2 Ziffern aufteilen (z.B: 23 in 2 und 3). Ich habe aber keine Ahnung ob es da einen passenden Befehl gibt.
Es gibt da passende Befehle ;) Die stehen in der BASCOM-Referenz. Das ist
nie nächste wichtige Lektüre ;)

Googeln ohne exakte Begriffe hat leider nix gebracht.
Dann geb ich dir mal nen Stichwort. Da die Zahlen nicht über zweistellig
rausgehen kann man einen Befehl zweckentfremden ... "BCD"
Such danach auch mal in der BASCOM-Referenz (die PDF von Hersteller MCS)

Wisst ihr da eine Methode oder einen Befehl um das zu machen? Was wäre eigentlich wenn ich z.B 7 Sekunden in einem Byte habe und dieses dann aufteile. Das sollte ja 0 und 7 ergeben oder?
Ich hab da was in der FAQ mit "BASCOM für Anfänger" und so. Da ist ne
Uhr beschrieben. Da kann man dann das Multiplexing und ein paar andere
Sachen abkupfern.

Boah, ist immer wieder schwer sich in neue Hardware reinzufinden, da die Software dann auch ihre Tücken mit sich bringt:) . Am meisten das 7 Segment Multiplexen zu den RTC Werten birgt so seine Probleme, wenn man es noch nie versucht hat.
Das kann ich wohl nachvollziehen :D
Das größte Problem ist eigentlich immer das man viel zu kompliziert denkt.
Wenn du ein Byte hast, dann sieh es nicht als Dezimalzahl sondern als
Ansammlung von Bits mit denen du rumspielen kannst wie mit den Kugeln
an nem Abacus. So kann man komplizierte Sachen auf recht einfache Art
erledigen.

Gruß
Dino
 
Boah, ist immer wieder schwer sich in neue Hardware reinzufinden, da die Software dann auch ihre Tücken mit sich bringt

... aber genau das macht es doch spannend. Sonst wäre es - wenigstens mir - zu langweilig!

Grüße und viel Erfolg!
 
Hallo Flo,


Es gibt da passende Befehle ;) Die stehen in der BASCOM-Referenz. Das ist
nie nächste wichtige Lektüre ;)

Bitte hilf mir auf die Sprünge. Ich hab grad die Hälfte der Referenz durch und hab einfach null Peil nach was genau ich suchen muss. Kannst du mir nen Begriff sagen nach dem ich suchen muss. Ich will auf keinen fall alles vorgekaut bekommen (dann lern ich ja auch nix dabei:) ) , aber ich bekomm langsam ne krise, weil das Ding bis Weihnachten fertig sein muss und die 7 Segment Anzeigen der dazugehörigen Uhr dank der wunderbaren Schieberegister andauernd schmarrn anzeigen.

mfg,
Flo
 
Hallo Flo,

Bitte hilf mir auf die Sprünge. Ich hab grad die Hälfte der Referenz durch und hab einfach null Peil nach was genau ich suchen muss. Kannst du mir nen Begriff sagen nach dem ich suchen muss.

Also du willst nen Byte in 2 Ziffern zerlegen. Das Byte kann in der Uhrzeit
keine Werte über 59 annehmen (max. 0..59 Min. , max. 0..23 Std, ...)
Also kann das Ergebnis nur 2stellig sein.

Man könnte also zB ne Binärzahl in BCD wandeln und dann die beiden Zeichen
trennen.

Beispiel ...
Binär : &b00010001
Hex : &h11
Dezimal : 17
BCD : 00010111
Hex vom BCD-Wert : &h17

zB so ...

Sec_bcd = Makebcd(_sec)
Min_bcd = Makebcd(_min)
Std_bcd = Makebcd(_hour)
Lcd Hex(std_bcd) ; ":" ; Hex(min_bcd) ; ":" ; Hex(sec_bcd) ; " "


ich hab da erst in BCD gewandelt und dann in Hex anzeigen lassen.
Damit kann man sehr schnell ne Ziffer mit 2 Stellen formatiert ausgeben.
Es gibt bestimmt noch andere und evtl auch bessere Lösungen. War aber
das was mir zu dem Zeitpunkt grade eingefallen ist. Man muß nur ein wenig
"mit den Bits spielen" ;)

Anders kannst du zB eine Zahl in 1er, 10er, 100er zerlegen indem du mit
Multiplikation, Division oder Modulo arbeitest.

schau mal auf Seite 245 der Referenz

bei 2 Stellen :
zahl = 49
zehner = zahl \ 10
einer = zahl MOD 10

bei 3 Stellen zusätzlich noch:
hunderter = zahl \ 100
zehner = zehner - (hunderter*10)

oder ne andere Lösung ...

Sec_bcd = Makebcd(_sec)
Sec_einer = Sec_bcd And &B0000_1111
Sec_zehner = Sec_bcd And &B1111_0000
Shift Sec_zehner , Right , 4

Ich tippe mal das diese Lösung für dich am besten umzusetzen ist.
Sieh mal auf Seite 364 der Referenz auf der unteren Seitenhälfte nach.
Mein Suchbefehl war dabei "nibble". Also ein Halbbyte.:hmmmm: Wenn ich
ehrlich bin gefällt mir die Lösung recht gut ... muß ich mal bei mir einsetzen :D

Probier mal ein wenig mit den Befehlen die mit Hex, BCD, IntegerDivision,
Modulo und Multiplikation zu tun haben. Wenn es noch Problemen gibt dann
melde dich einfach nochmal.

Hier ist mal mein Proggi für nen Mega128 bei dem ich auch mit I2C, DS1307
und nem LCD gespielt habe ... Anhang anzeigen EvalBoard_m128_I2C_DS1307_v02.bas
Evtl kannst du ja was draus gebrauchen ... ;)

Gruß
Dino
 

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