Bascom Binär-Uhr mit RTC

Hm, wenn ich _sec=12 habe und schreibe portb=_sec, dann leuchten an den portb angeschlossene Led im binären Muster 00001100 (wenn ich mich nicht verrechnet hab). Natürlich ist das byte der Variablen _sec mit den gleichen bitmuster belegt. Die 12 ist ein dezimaler Wert. So ist es doch gewollt, ober bin ich auf einer total anderen Schiene?
 
Hmm....,
Die ds3231liefert 2 decimal zahlen im bcd format in einem byte.
Jede Zahl hat den Wertebereich von 0-9.
Im oberen nibbels kann gemaess sekundenbereich der Bereich von 0-5 und im unteren nibbel 0-9 annehmen.
Also die 12 wuerde dann so aussehen 0001 0010.
Mfg
Addi
P.s
Meine Reihenfolge der darstellung erfolgt msb gemaess
 
wenn ich _sec=12 habe und schreibe portb=_sec,
Vollkommen richtig, so hat er das mit dem internen Oszillator als Taktquelle ja auch erfolgreich gemacht.
Dann wollte er aber wegen der besseren Genauigkeit (und inzwischen wohl auch der Überbrückung von Abschalt-/Ausfallzeiten) 'ne externe seriell angebundene (TWI) RTC verwenden.
Und wenn er die ausliest während der Sekundenzeiger auf der Zwölf steht, liefert die RTC eben nicht binär-Zwölf (&B0000_1100), sondern 'ne gBCD mit dem Zehner "Eins" als highnibble, und dem Einer "Zwei" als Lownibble. _sec ist dann also &B0001_0010, was einer binären 18 entspräche.
irgend einen Unsinn. 1,2,3,4,5,6,7,8,9,16
0001 0000 = 10 in BCD (Binary Coded Decimal)
0001 0000 = 16 in Binär
Es ging darum, wie er aus der gBCD 'ne korrekte Binärzahl bekommt (daß _sec eben 12 zugewiesen bekommt und nicht 18) - das dann auf den Ports binär auszugeben, war nicht das Problem...

Edit: Addi war mal wieder schneller

Edit2: hatte ich übrigens direkt über @Tschoeatsch 's Frage fast genau so geschrieben:
Und genau das macht der Sensor.
Im Highnibble steht die (dezimale) Zehnerstelle (also Ziffer kleinergleich 9, als BCD), im Lownibble die Einerstelle.
Bei ... Zweiundvierzig Minuten liefert der Sensor im Highnibble 'ne "4", und im Lownibble 'ne "2".
Also &B0100_0010, was eigentlich 66dez entspricht. Die Frage war seit #5, wie man jetzt von der 66 (0100_0010) zur korrekten 42 (0010_1010) kommt.
Okok, nicht mit Zwölf Sekunden, aber...
 
Zuletzt bearbeitet:
Bin ich jetzt zu doof? Die Rtc liefert im bcd-code, klar. Wende ich auf diese bcd-Variable den makedec an, steht in der neuen Variablen der Wert der Rtc in binär drin, lass ich mir diesen Wert am Lcd anzeigen, steht er dezimal da. Also die 12 Sekunden kommen aus der Rtc 00010010, nach makedec 00001100, das aufs Lcd steht dann da 12.
 
Wir drehen uns im Kreis...
Gerd hatte nach dem Umbau auf die externe RTC für ihn unplausible Ergebnisse und deswegen das Thema (mit Beitrag #1) eröffnet.
addi, Dino und ich haben dann in #2, #3 und #4 geklärt, daß der Sensor gepackte BCDs übermittelt.
In #5 hat Gerd diese Antwort(en) zur Kenntnis genommen, und nachgefragt, wie man die gepackte BCD nach binär wandeln könne (möglichst ohne großen Aufwand, vielleicht mit wenig Bitschubserei).
In #6 hat Dirk als Lösungsvorschlag einen Bascom-Code-Schnipsel aus dem Ärmel geschüttelt.
In #9 habe ich zu Dirks Vorschlag angemerkt, daß eine Multiplikation mit 10 drin ist - wegen "ohne großen Aufwand". Natürlich ohne die Korrektheit anzuzweifeln.
In #10 habe ich deswegen den Ansatz eines optimierten Vorschlages entworfen.
In #13 hast Du dann Makedec als Bascom-Onboard-Lösung empfohlen
In #14 hat Gerd die Korrektheit von Dirks Vorschlag bestätigt
In #15 hat Dino nochmal indirekt auf Makedec hingewiesen, Dirk in #16 dann auf Dein #13
In #17 hat Gerd Makedec ignoriert, da er ja nach binär, und nicht nach dezimal wandeln wollte. Außerdem hatte er nochmal die mögliche Existenz eines einfachen mathematischen Algorithmus in den Raum gestellt
In #18 habe ich dann darauf hingewiesen, daß dieser Algorithmus mMn eben genau mein Weg wäre, und habe dazu zwei Code-Schnipsel eingeworfen (einmal mit Bascom selbst, und einmal mit Inline-ASM.
Außerdem habe ich zu den Onboard-Mitteln gesagt: "Makedec ist, was Du suchst", und hinterher Makedec "auseinandergenommen".

Bis hier hatten wir also das ursprüngliche Problem (gBCDs statt binär) geklärt, und für die Behebung sogar drei funktionierende Lösungen, und wir wissen sogar, welche Version wie effizient arbeitet. Gerd kann die Lösung seiner Wahl verwenden.

Ab #19 gings dann mehr oder weniger wieder von vorn los...
 
Na, dann bin ich vielleicht nicht so doof :rolleyes: Das wir aneinander vorbei schreiben, hab' ich befürchtet, da ich aber von deiner Kompetenz überzeug bin, suchte ich eher bei mir einen Fehler. Aber es passt ja alles :good3:
 
Habe übrigens in @Dirk s Code (#6) noch einen Fehler gefunden, den Gerd (#14) ein wenig ... ineffizient behoben hat.
Dirk kopiert sich in Zeile 10 BCDdata in 'ne Extravariable MSBdata, shiftet aber dann BCDdata statt MSBdata.
Gerd hat zur Korrektur dann einfach ab Zeile 20 komplett mit BCDdata weitergerechnet. Dadurch wird natürlich der Inhalt von BCDdata verändert. Wenn das akzeptabel ist, kann man sich das vorherige kopieren sparen.

Soo...
hab mal versucht, Dirks und meinen Weg als Bascom-Subroutine umzusetzen:

CodeBox BascomAVR
$regfile = "m8def.dat"
$crystal = 8000000
Dim Bcd_in As Byte , Bin_out As Byte
Declare Function Makedec_dirk(byref Bcddata As Byte ) As Byte
Declare Function Makedec_lotadac(byref Bcddata As Byte) As Byte

Bcd_in = &B01000010  '&B01000010  'Zweiundvierzig als gBCD

Bin_out = Makedec(bcd_in)  'Bascom-Makedec
Bin_out = 0

Bin_out = Makedec_dirk(bcd_in)  'Dirk
Bin_out = 0

Bin_out = Makedec_lotadac(bcd_in)  'LotadaC
Bin_out = 0

End  'end program


'****************Subroutinen*****************
Function Makedec_dirk(byref Bcddata As Byte ) As Byte
  Dim Lsbdata As Byte , Msbdata As Byte
  Lsbdata = Bcddata And &B00001111  '"Einer" extrahieren
  Msbdata = Bcddata
  Shift Msbdata , Right , 4  '"Zehner" extrahieren
  Makedec_dirk = 10 * Msbdata  '"Zehner" ausrechnen
  Makedec_dirk = Makedec_dirk + Lsbdata  'Summieren
End Function

Function Makedec_lotadac(byref Bcddata As Byte) As Byte
'Der Funktionsaufruf pusht erst die SRAM-Adresse von Makedec_lotadac,
'danach die vom Parameter Bcddate (byref) auf den Softstack.
'Dieses PUSHen geschieht über das X-Doppelregister,
'X zeigt also beim Eintritt in die eigentliche Funktion auf den letzten Parameter
  $asm
  LD R16, X  'BCDdata laden
  MOV R17, R16  'Kopie für "Einer"
  ANDI R17, &b00001111  '"Einer" extrahieren
  ANDI R16, &b11110000  '"Zehner" extrahieren
  LSR R16  '"Zehner"*8
  ADD R17, R16  'zum "Einer" addieren
  LSR R16
  LSR R16  '"Zehner"*2
  ADD R17, R16  'zum "Einer" addieren
  Loadadr Makedec_lotadac , X  'Makedec-Adresse nach X laden
  ST X, R17  'Ergebnis abspeichern
  $end Asm
End Function

Das Original-Makedec braucht (wie vorhergesagt) variabel viele Takte, im worst case ("Neunundneunzig") sinds 63Takte.
Dirks Weg benötigt ca. 100 Takte, was neben dem Subroutinen Overhead (ca. 15 Takte) vor allen Dingen an den vielen SRAM-Zugriffen liegt (bei jedem Lese- und Schreibzugriff wird die Variable aus dem SRAM gelesen/dorthin geschrieben). Trotz automatischer Verwendung der MUL-Instruktion.
Mein Weg braucht konstant 37 Takte. Bascom für die Vierziger 38 Takte, von 0..9 nur 18 Takte.
Besser bekomme ich es mit sauberen Funktionen nicht hin (wie gesagt erzeugt bereits die Subroutine selbst beim Aufruf 15 Takte) - Bascom-Makedec macht das nicht, und kann außerdem auf die Adressen der Variablen direkt zugreifen. Ich muß mir die erst aus dem Softstack ziehen (Softstack in Pointer-Register laden, und dann indirekt laden/speichern).
 

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