Bascom Binär-Uhr mit RTC

gerd51

Mitglied
18. Jan. 2013
43
0
6
Sprachen
  1. BascomAVR
Hallo Freunde der gepflegten Frickelkunst.

Habe hier noch ein paar Plexiglasabfälle und wollte daraus eine simple Binäruhr bauen. Habe den internen 8 MHz Takt benutzt und entsprechend Sekunden, Minuten und Stunden hochzählen lasssen. Die Ergebnisse direkt auf die entsprechenden Ports eines Atmega16 gegeben. Alles läuft einwandfrei aber sehr ungenau.
Habe eine RTC 3231 angeschlossen. Die systemvariablen _sec, _min, _hour jetzt stattdessen auf die Ports gelegt. Jetzt zählt er irgend einen Unsinn. 1,2,3,4,5,6,7,8,9,16 ....?????????????????????
Kann sich und mir das einer erklären?
Gruß Gerd
 
Hallo Gerd,
Die ds3231 gibt die betr. Werte im bcd format aus...also nur die die betr. Nibbels betrachten.
Mfg
Addi
 
Hi,

jou ... wie von addi geschrieben ... sieht nach Verwechselung von BCD und Binär aus ...

0001 0000 = 10 in BCD (Binary Coded Decimal)
0001 0000 = 16 in Binär

Bei BCD hast du als unteres Nibble die Einer und als oberes Nibble die Zehner.

Gruß
Dino
 
Hmm...
Da das ganze ja über TWI/IIC geht, muß er entweder selbst das Uhrwerk angepaßt haben (und auch das Datenblatt der RTC gelesen und umgesetzt haben), oder irgendeine Bibliothek dazu verwendet werden, deren Ersteller dann die entsprechenden Werte irgendwie hätte extrahieren müssen.

Aber nehmen wir mal an, _sec, _min und _hour wird einfach der Inhalt der jeweiligen Scratchpad-Adressen der RTC zufgewiesen...
Bei den Minuten und Sekunden stimmt das mit dem BCD (wobei Bit7 immer Null ist, da Sekunden-/Minutenzehner nie größer als 5 dezimal = 0101 binär sein können).
Bei den Stundenzehnern wäre das Maximum 2 dezimal = 0010 binär. Bit7 ist immer Null, Bit6 indiziert den 12- oder 24-StundenModus. Bit6 ist im 24h-Modus die binäre "2", im 12h-Modus indiziert es AM/PM.

Wie arbeitet das ganze im AVR jetzt eigentlich?
Wenn der interne Takt die Uhr bestimmt, kann man (mit dessen Genauigkeit) Interrupts erzeugen lassen, zB im Sekundentakt.
Durch den Interrupt kann man die Zeit-Variablen "weiterticken", eine "statische" Anzeige muß hier aktualisiert werden (wenn die Anzeige in irgendeiner Form gemultiplext wird, muß die eh ständig "aktualisiert" werden).
Was bringt mir die RTC (abgesehen von der Genauigkeit)?
Wenn ich nur wissen will, wie spät es gerade ist, brauch ich gar kein internes Uhrwerk mehr im AVR, ich lese einfach den tatsächlichen Zustand aus der RTC.
Will ich aber 'ne genaue Anzeige, müßte ich quasi ununterbrochen die RTC auslesen, mit dem ganzen TWI-Overhead. Um den Wechsel der Sekunde nicht zu verpassen.

Allerdings kann die RTC selbst seine 32,768kHz ausgeben, oder mit dem Interrupt-Ausgang (unter anderem) 1Hz.
Damit könnte man dann ähnlich dem AVR-Takt ein internes Uhrwerk realisieren, das so genau wie die RTC ist, den Interrupt zum aktualisieren der Anzeige genau trifft, und keine ständige Kommunikation mit der RTC erfordert. Nur zum "Stellen" der AVR-Uhr (PowerUp usw)
 
Hallo erstmal,
vielen Dank für die Tipps. Der Unterschied zwischen BCD und binär war mir, Asche auf mein Haupt, nicht bewusst gewesen.:banghead: .:(. Die Lösung von LotadaC ist mir klar und habe sie jetzt mal so umgesetzt, aber was ist bei Stromausfall? Gibt es eine Möglichkeit, ohne großen Aufwand, bcd nach binär zu wandeln ( irgendeine Bit-Schieberei)?
 
bcd nach binär zu wandeln

Hallo Gerd,
das könnte in etwa so aussehen:

(Ich programmiere nicht in BascomAVR, eventuell gibt es etwas einfacheres oder fertiges bei Bascom, ich weiß auch nicht, ob der Syntax richtig ist)

Dirk :ciao:



CodeBox BascomAVR
Dim BCDData as Byte
Dim LSBData as Byte
Dim MSBData as Byte
Dim BINData as Byte

Databyte = &H52   ' Test: 5 high nibble, 2 low nibble


LSBData = BCDData and &B00001111  
MSBData = BCDData  
Shift MSBData , Right , 4

ResultByte = (10*MSBData)+LSBData ' 52 decimal, 0B00110100
 
Zuletzt bearbeitet:
Hallo Gerd,
Die meisten ds3231 module sind mit einer Batteriehalterung versehen. Falls es sich um ein 'nacktes' IC handeln sollte, im ds3231 Datenblatt ist ein Schaltungsbeispiel mit Batterie angegeben.
MfG
Addi
 
aber was ist bei Stromausfall?
Wie Addi sagte, das RTC kann mit einer Pufferbatterie weiterlaufen, mein Vorschlag lief ja letztlich darauf hinaus, daß der AVR sich beim PowerUp (Stromausfall usw) die korrekte Zeit aus der RTC holt. Außerdem vielleicht noch einmal am Tag, um Schaltjahre mitzuerschlagen... Kennen RTCs auch Sommer-/Winterzeit??
Zum BCD-binär-konvertieren hat Dirk schon was gesagt, bei den Stunden stehen im Register der RTC aber noch weitere Infos in den Bits - inwiefern Deine Bibliothek die bereits wegmaskiert bzw auswertet, weiß ich nicht. Ich würde die drei Bytes bei Bedarf zu Fuß auslesen... und bei Interesse die beiden Temperaturregister gleich mit...
 
Gibt es eine Möglichkeit, ohne großen Aufwand, bcd nach binär zu wandeln ( irgendeine Bit-Schieberei)?
Das kommt darauf an.
Hier zB auch, welchen Controller Du verwendest.
Vorweg: Als Programmierer in einer Hochsprache kann Dir das weitgehend egal sein, aber vielleicht interessiert Dich doch, was letztendlich im AVR geschieht.
Wenn Du Dir @Dirk s Code ansiehst, sind da eigentlich nur simple "Bitschubsereien", Byteadditionen usw drin.
Nur in Zeile 13 findest Du ein unscheinbar wirkendes "10*MSBdata"
Multiplikation mit 10 ist für einen binären Controller so schön einfach, wie für Dich (dezimaler "Controller") das Einmaleins mit der 77.
Um zwei Bytes zu miltiplizieren, muß 'ne ganze Menge geschoben, verglichen und addiert werden (hatten wir mMn hier schon mal irgendwo).
Warum kommts dann auf den Controller an?
Weil einige Controller Bytes direkt multiplizieren können, andere nicht.
Normalerweise muß man bei solche Produkten beachten, daß das Ergebnis größer als ein Byte werden könnte - Du weißt aber, daß der eine Faktor immer zehn ist (0b1010), und der andere als Nibble höchstens 15 sein könnte (als BCD sogar nur 9, und da das hier die Zehnerstelle einer Uhrzeit betrifft sogar nur 5) - jedenfalls ist das Ergebnis immer kleiner 256.
Man könnte also die Multiplikation sogar optimieren - Bascom wird aber entweder zu Fuß auf normalem binärem Wege multiplizieren, oder normal die Multiplikationsinstruktionen nutzen. Je nachdem, ob der Controller die eben kann, oder nicht.

(kannst ja Spassenshalber mal Dirks Code für einen Tiny2313 und einen Mega88 kompilieren lassen und die resultierenden Codegrößen vergleichen. Und je im Simulator die Zeit/Takte, die Zeile 13 braucht.)
P.S.: Hatte jetzt nicht unbedingt was mit der Eigentlichen Frage zu tun, aber vielleicht kannst Du trotzdem was draus lernen...
 
Gibt es eine Möglichkeit, ohne großen Aufwand, bcd nach binär zu wandeln ( irgendeine Bit-Schieberei)?
Und zum dritten, da ist jetzt nur Thomas dran schuld :p :
@LotadaC du bist ja auch eine hochqualifizierte Bitschubse.
Aaalsoo...
Es handelt sich hier natürlich nicht um BCDs (eine binary coded digit ist logischerweise bereits binär, die binäre Zahl hat genau den Wert der Dezimalstelle (digit).
Du hast gepackte BCD, das heißt das untere Nibble enthält die Einer, das Obere die Zehner (den Rest bei den Stunden vernachlässige ich jetzt mal).
Ein Nibble selbst ist also die korrekte, binäre 4bit-Zahl.
@Dirk hat Dir ja bereits gezeigt, wie das dann geht: Du separierst die beiden Nibbles (Digits). Da das Zehnernibble den zehnfachen Wert haben müßte, multiplizierst Du es mit zehn, und addierst es zum Einernibble. Fertig.
Wie Bascom das ganze, insbesondere die Multiplikation macht, braucht Dich nicht wirklich zu interessieren.

Aber da Thomas mich ja herausgefordert hat hier mal ein Weg, wie man das im AVR angehen könnte:
Vorüberlegung:
Wie multipliziert man binär? Genauso, wie man das schriftlich in der Schule gelernt hat. Mit zwei wesentlichen Unterschieden:
Erstens arbeitet man auf der Basis zwei (statt auf 10, also beim verschieben verdoppelt/halbiert man, anstatt zu zehnteln/verzehnfachen),
Zweitens gibt es nur zwei Ziffern (also das kleine einmaleins beschränkt sich auf vier Gleichungen (0*0=0, 1*0=0, 0*1=0, 1*1=1))
Wie hat man nun dezimal schriftlich Multipliziert? Im Prinzip hat man einen Faktor in seine Zehnerpotenzen aufgeteilt, diese je mit dem anderen Faktor multipliziert, und die Ergebnisse addiert.
Beispiel:
15*23

also 15*2(*10)=30(*10)=300
15*3(*1)=45(*1)=45

Zusammenaddiert also 345.
(Die Zehnerpotenzen in den Klammern hat man nicht wirklich mitgeschrieben, sondern durch die Treppenartige Anordnung dazugeschummelt.

Binär geht das genauso, nur eben mit Zweierpotenzen (also Schiebeoperationen und Additionen). Ich will jetzt hier das ganze nicht ausführen - letztlich ist es wegen Basis zwei viel einfacher. Es läuft darauf hinaus, einen der Faktoren in Zweierpotenzen zu zerlegen (was durch einfaches schieben realisiert wird), den anderen Faktor mit dessen uhrsprünglicher Bitwertigkeit (auch durch schieben) und dem Bit selbst zu Multiplizieren (Zur Erinnerung: Das Bit ist eins oder Null). Man hat also entweder einen geschobenen Faktor oder Null zu addieren. Also kann man genausogut schieben, und anhand der Bits des ersten Faktors entscheiden, ob dieses geschobene Teilergebnis mitsummiert werden muß, oder nicht.

Weiter:
Der hier verwendet konstante Faktor ist Zehn (0b1010) - da würden also nur zwei geschobene Zwischenergebnisse addiert werden (Nibble*8+Nibble*2).

Und zuletzt:
Das Zehnernibble ist das Highnibble der gepackten BCD - statt das erstmal nach rechts zu schieben, um es dann mehfach nach links zu schieben, kann man es auch mehrfach nach rechts schieben.

soooooooooooooo... los gehts

  1. gepackte BCD in ein Rechenregister (nennen wir es Arbeitsregister) laden
  2. von dort ins Ergebnisregister kopieren
  3. dort das Highnibble wegmaskieren (Ergebnis=Einer. bisher vier Systemtakte)
  4. im Arbeitsregister das Lownibble wegmaskieren
  5. Arbeitsregister einmal rechtsschieben (entspricht Faktor einhalb, aber da es ja im Highnibble statt im Lownibble steht (Faktor 16) entspricht das zusammen Faktor 8)
  6. Arbeitsregister zum Ergebnisregister hinzuaddieren (Ergebnis=Einer+(8*Zehner). weitere drei Takte
  7. Arbeitsregister noch zweimal rechtsschieben (über vier zu zwei)
  8. Arbeitsregister zum Ergebnisregister hinzuaddieren (Ergebnis=Einer+(8*Zehner)+(2*Zehner). weitere drei Takte
  9. Ergebnis abspeichern (zwei Takte)
Fertig nach 12 Takten, wobei ein drittel auf das Laden und Speichern der Variablen aus dem/ins SRAM entfallen.

Edit: Das ist der Weg ohne interner Multiplikationsinstruktion. Gehts mit schneller?
Hmm...
Das Multiplizieren sind oben die Schritte 5 bis 8. Zusammen 5 Takte.
MUL selbst kostet zwei Takte, aber da es kein MULI gibt, muß erstmal die Zehn als zweiter Faktor in ein Rechenregister geladen werden (1 Takt).
Wenn wir die BCD mit 10 multiplizieren wollen, muß sie als Low Nibble im Rechenregister stehen. Also vorher viermal rechtsschieben? Wären vier weitere Takte. Wären also bereits sieben. Ok, Schritt 4 wäre dann auch überflüssig, hat aber auch nur einen Takt.
Nur dreimal rechtsschieben (3 Takte), und statt mit zehn mit 5 Multiplizieren? Dann brauchts das Maskieren, also auch hier ein Takt mehr.
Und wenn man nicht schiebt, sondern die Nibbles tauscht?
Also statt 5..8
Nibbles im Arbeitsregister tauschen (Swap - ein Takt)
Zehn in weiteres Rechenregister laden (ein Takt)
Arbeitsregister mit Zehn-Register multiplizieren (zwei Takte)
Multiplikationsergebnis (aus R0) auf das Ergebnisregister addieren (ein Takt)

wären dieselben fünf Takte...
 
Zuletzt bearbeitet:
  • Like
Reaktionen: TommyB
@LotadaC :
Bzgl. Dst Problematik, maxim hat da eine app Note bereitgestellt. Suche im Netz nach rtc with dst.
Mfg
Addi
 
Hmm...
AppNote3778 oder was?
Kernaussage 1: Es gab mal RTCs die das selbständig konnten (zu welchen Wechselzeiten auch immer
Kernaussage 2: aktuelle RTCs machen das nicht mehr, stattdessen soll die Firmware im Controller das machen

Es wird vorgeschlagen, jede Stunde zu prüfen, obs 02:00 ist, und dann das Datum (warum nicht andersrum - wären viel weniger Abfragen).
Der Algorithmus versagt, wenn der Controller zu dem Zeitpunkt gerade aus ist.
Sinniger wäre also, den derzeitigen DST-Zustand in der Firmware nichflüchtig abzulegen, und beim syncen mit der RTC zu Prüfen, ab man sich im selben DST-Bereich befindet.
Oder auf andere Synchronisationsquellen (Frankfurt, GPS) zurückzugreifen...
 
Hi Gerd, schau mal in der bascom-Hilfe unter 'makedec', 'makebcd'... Da gibt's passendes für deine RTC
 
Hallo erstmal,
vielen Dank für eure schnelle Hilfe und kompetenten Tipps.
@ Dirk Habe deinen Code mal in BASCOM übersetzt ;):). Die Idee war genial. Klappte sofort.
Hier mal ausschnittsweise den Code ohne Dimensionierung.

CodeBox BascomAVR


Getdatetime:
  I2cstart  ' Generate start code
  I2cwbyte Ds3231w  ' send address
  I2cwbyte 0  ' start address in 3231

  I2cstart  ' Generate start code
  I2cwbyte Ds3231r  ' 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

Bcddata = _sec  
LSBData = BCDData and &B00001111
MSBData = BCDData
Shift Bcddata , Right , 4
Resultbyte = 10 * Bcddata 
Bindata = Resultbyte + Lsbdata

Return


Gruß an alle Frickelfreunde
Gerd
 
Hi,

für BCD-Wandlungen gibts auch extra Befehle bei Bascom.
Schau mal in die Befehlsreferenz.
Das macht die Arbeit wesentlich einfacher und übersichtlicher.

Gruß
Dino
 
Hallo Freunde,
in der Hife und den Befehlsreferenzen gibt es nur Wandlerbefehle von bcd to dezimal, dezimal to bcd, string in bcd, aber keine bcd to binär. Dies geht ausschließlich auf dem von Dirk vorgechlagenen Weg.
Nach längerem Suchen habe ich auch ein Beispielprogramm bcd.bas bei msc gefunden, das genau auf dieser Idee beruht. Ich glaube es heißt bcd.bas.
Eventuell gibt es noch einen mathematischen Algorithmus, aber ich hatte keine Lust den zu entwickeln.
 
Eventuell gibt es noch einen mathematischen Algorithmus, aber ich hatte keine Lust den zu entwickeln.
Hatte ich doch schon in #10 erklärt.
Analog zu Dirks Code wäre das


CodeBox BascomAVR
Result = BCDData and &B00001111
temp = BCDData  and &B11110000
shift temp, right, 1
result=result+temp
shift temp, right, 2
result=result+temp


in der Hife und den Befehlsreferenzen gibt es nur Wandlerbefehle von bcd to dezimal, dezimal to bcd, string in bcd, aber keine bcd to binär.
Ok, die Bezeichnung dezimal ist da irreführend, außerdem müßte es gepackte BCD heißen, aber "Makedec" ist, was Du suchst.
Extra für Dich hab ich mir jetzt natürlich auch nochmal angesehen, was "Makedec" wirklich macht:
  1. das Argument (also die gepackte BCD) wird aus dem SRAM nach Register25 geladen (direkt mit LDS)
  2. anschließend nochmal ins Register24 kopiert und...
  3. ...dort das Highnibble wegmaskiert (R24 enthält jetzt also mit dem LowNibble nur noch den einer)
  4. von Register25 wird jetzt in einer Schleife sooft 0x10 abgezogen, bis es dabei zu einem Überlauf kommt (Abbruchbedingung mittels Carry, also solange das Highnibble vor der Subtraktion größer 0 war), und solange dabei kein Überlauf stattfand, wird jedesmal 10dez auf Register24 addiert (SUBI mit 246)
  5. Nach der Schleife steht das Ergebnis in R24, und wird (indirekt mit ST X...) ins SRAM gespeichert.
Die Punkte 2..4 sind in einer Subroutine, deswegen ist das definitiv langsamer als mein Weg in #10.
Würde man darauf verzichten und bei außerdem bei Punkt 5 auch direkt speichern, würde das konvertieren einer "einstelligen" gepackten BCD (also kleiner 0b0001_0000) 9 Takte brauchen.
Für jeden Zehner kommt ein Schleifendurchlauf mit 5 Takten dazu.
Muß ich mir jetzt den Maschinencode von Dirks Programmschnipsel auch nochmal zu Gemüte führen?

P.S.: Was Bascom aus meinem Codeschnipsel da oben machen würde, kann ich so nicht vorhersehen, aber eigentlich sollte es sehr einfach mit Inline-Assembler gehen.
wenn Du also Bcddata und Bindata als Bytes definiert hast, und Bcddata selbstredend das gepackte BCD enthält, sollte folgendes gehen:


CodeBox BascomAVR
$Asm
LDS R16, {Bcddata}
MOV R17, R16
ANDI R17, &h0F
ANDI R16, &hF0
LSR R16
ADD R17, R16
LSR R16
LSR R16
ADD R17, R16
STS {Bindata}, R17
$End asm
 
Zuletzt bearbeitet:
Ich raller das jetzt nicht. Ich dacht, Gerd hat an seinen ports die Leds dran, je einen port für Stunden, Minuten, Sekunden und die sollen binär die Zeit darstellen. Dann setzt doch der port von dezimal auf binär um. :confused:
 
Dann setzt doch der port von dezimal auf binär um.
Nichtmal das wirklich. Dezimal gibts so im AVR gar nicht, das ist bereits binär. Gibst Du es direkt auf den Port aus, erscheint dort das binäre Muster.
Wenn Bascom sagt, der Controller soll fünf plus sieben rechnen, dann rechnet er binär &B00000101 + &B00000111.
Die Umwandlung von vorgegebenen Dezimalen Konstanten usw im Bascom-Code übersetzt Bascom beim compilieren des Programmes ins binäre.

Du kannst jetzt natürlich den Wertebereich eines Bytes nur von 0..9 nutzen, dann entspricht das einem BCD. Dabei blieben die oberen vier Bits (Highnibble) immer 0 (9dez=&B00001001).
Packt man zwei BCDs in die beiden Nibbles eines Bytes, hat man ... genau ... gepackte BCDs.
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.
Dirks Vorschlag rechnet letztendlich Lownibble + (10* Highnibble), also 0000_0010 + (0000_1010 * 0000_0100) = 0000_0010 + 0010_1000 = 0010_1010
Schwierig/aufwändig ist dabei die Multiplikation. Dabei werden zwei Bytes je achtmal geschoben, und bis zu 8 Additionen ausgeführt.
Bei der Konstanten Zehn (0000_1010) sind es nur zwei Additionen (die mit der "1"), und ich weiß auch schon vorher, wieviel zu schieben ist, den Rest spar ich mir. Dadurch reduziert es den Aufwand so sehr, daß auch die Verwendung einer MUL-tiplikationsinstruktion nicht schneller ist (wenn der Controller sie denn kann).
Das war mein Vorschlag.
Makedec von Bascom geht einen anderen Weg. Es prüft, wie oft man vom von der Zahl 'ne Highnibble-Eins (0001_0000) abziehen könnte, und addiert dabei jedesmal 'ne Zehn (0000_1010) auf das vorher extrahierte Lownibble.
Also zurück zur Zweiundvierzig (als gepackte BCD 0100_0010)
Lownibble in Ergebnisbyte extrahiert (Ergebnis=0000_0010)
Von der gBCD 'ne HighnibbleEins abgezogen
0100_0010 - 0001_0000 = 0011_0010, kein Überlauf, also Ergebnis = 0000_0010 + 0000_1010 = 0000_1100
Nochmal
0011_0010 - 0001_0000 = 0010_0010, kein Überlauf, also Ergebnis = 0000_1100 + 0000_1010 = 0001_0110
Nochmal
0010_0010 - 0001_0000 = 0001_0010, kein Überlauf, also Ergebnis = 0001_0110 + 0000_1010 = 0010_0000
Nochmal
0001_0010 - 0001_0000 = 0000_0010, kein Überlauf, also Ergebnis = 0010_0000 + 0000_1010 = 0010_1010
Nochmal
0000_0010 - 0001_0000 gibt'n Überlauf, also sind wir fertig. Im Ergebnis steht 0010_1010 also 42dezimal.

Bei 'ner Neun im Highnibble kämen ein paar "Nochmal"s dazu...
 

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