Unterrichts- und Lernmaterial für Mikrocontroller
Unterrichts- und Lernmaterial fürMikrocontroller

Assembler Kurs

1 - Was wird benötigt?

Bewährt hat sich ein erster Zugang über BASCOM. Ein Assembler-Programm lässt sich in seinem Editor genau so erstellen wie man vorher bereits BASIC Programme geschrieben hat. Der Unterschied: man muss neue "Vokabeln" lernen und sich mit der neuen Syntax und benutzten Hardware etwas intensiver auseinandersetzen, als es bei einer Hochsprache notwendig ist. Das Datenblatt eines Controllers gehört ab sofort mit zur unverzichtbaren Lektüre.

Wer bisher ausschließlich in Hochsprachen programmiert hat (BASIC, PASCAL, C o.ä.) wird umlernen und sich deutlich mehr auf die physikalische Ebene einlassen müssen, um die in einem Controller ablaufenden Prozesse besser verstehen und umsetzen zu können.

Parallel zum BASCOM Compiler wird die ebenfalls kostenfrei im Internet erhältliche integrierte Entwicklungsumgebung AVR Studio in der Version 4.19 benutzt; in diesem Kapitel nur zur Simulation von Programmen und als Debugger. Ab "AVR Assembler - Teil 1" folgt ein umfassender Einstieg in Assembler mit AVR Studio 4.19.

Abbildung 1 - Grundausstattung BRENNER für den Assemblerkurs (GA_BR): AVR-Brenner mit Nullkraft-Sockel

Für die Arbeit mit BASCOM wird als Hardware ein Brenner möglichst mit Nullkraftsockel, ein Steckbrett für den Aufbau von Schaltungen (auch dieses möglichst mit Nullkraftsockel) und eine Energiequelle benötigt.

Abbildung 2 - Grundausstattung ANWENDERSCHALTUNG (GA_AS) für den Assemblerkurs: Nullkraftsockel, Steckbrett und Batteriehalter für 3 x AA Batterien

Als Energiequelle eignet sich auch - falls vorhanden - jedes Controller-Board mit herausgeführten  Buchsen über +5V und/ oder +3,3V.

2 - Die eingesetzte Software

Wie ich bereits sagte, reicht das Programm BASCOM als Editor und Compiler für die ersten  Assemblerprogramme völlig aus. Als Debugger und vor allem Disassembler ist es nicht geeignet; dass übernimmt das kostenfreie Programm AVRStudio in der etwas älteren Version 4.19. Die neueste Version 7 von ATMEL kommt deutlich behäbiger und langsamer daher als die Version 4.x und sie erkennt unter Windows 10 die Schnittstellen von angeschlossenen Debuggern und Brennern, wie zum Beispiel dem AVR Dragon, nicht. So etwas ist in der Schule oder im Hobbybereich m. E. nicht zu gebrauchen. Die Dinge müssen funktionieren und nicht erst durch Patches oder Herumgelöte lauffähig gemacht werden.

3 - Einstieg in AVRStudio 4.19

Nach dem Herunterladen und der Installation des Programms öffnet sich der Startbildschirm von AVR Studio mit verschiedenen Auswahlmöglichkeiten.

  • Anlegen eines neuen Projektes (New Project) oder
  • Öffnen eines bestehenden Projektes (Open) oder
  • Abbruch (Cancel) und Übergang zum leeren Eröffnungsbildschirm.

Wähle in diesem Fall

  • Anlegen eines neuen Projektes (New Project)
Abbildung 3 - Startbildschirm von AVR Studio 4

In dem sich öffnenden Welcome-Bildschirm werden folgende Eintragungen vorgenommen

Abbildung 4 - Festlegung von Projektname und Arbeitsdateiname und Arbeitsverzeichnis

Project Type : Atmel AVR Assembler

Project Name: LEDs

Initial file      : LED_0.asm

Location        : Arbeitsverzeichnis auf dem eigenen Rechner

 

Abgeschlossen werden die Eintragungen mit einem Klick auf den Button Next >>. Im folgenden Bildschirm wird die Plattform für den Debugger und der in der Schaltung benutzte Controller ausgewählt.

Abbildung 5 - Einstellung des Simulators und Auswahl des eingesetzten Controllers.

Folgende Einstellungen werden vorgenommen:

Debug platform: AVR Simulator 2

Device                : ATtiny13A

Die Eingaben werden mit Finish beendet und AVRStudio meldet sich mit einer neuen Arbeitsoberfläche zurück.

Abbildung 6 - Hauptbildschirm unter AVR Studio 4.x

Ganz links befindet sich das Projekt-Fenster, in dem alle Dateien für das aktuelle Projekt LEDs gelistet sind. In der Mitte ist das Editor-Fenster, in das der Quellcode eingegeben wird und rechts oben das I/O Ansicht - Fenster.

Klickt man im Fenster I/O Ansicht vor dem Eintrag PORTB auf das Plus-Zeichen, öffnet sich ein Unterfenster mit den drei Registern: Data Register - Port B, Data Direction Register - Port B und Input Pins - Port B.

Abbildung 7 - I/O Ansicht Fenster

Im darunter befindlichen Fenster werden die drei Register mit ihrem jeweiligen Namen, der Adresse und den Bits angezeigt.

Einen ersten Zugang zum AVRStudio verschaffen wir uns im folgenden Abschnitt mit einem sehr kleinen Assemblerprogramm.

4 - Assembler Testprogramm

Aufgabe

  • Übertrage das Programm LEDs.asm in den Editor von AVR Studio.
Abbildung 8 - Assemblerprogramm LEDs.asm im Editor von AVR Studio eingegeben.
  • Compiliere anschließend das Programm mit Build - Build.
  • Starte den Debugger mit Debug - Start Debugging. Ein gelber Pfeil sollte jetzt auf das erste Kommando im Editorfenster zeigen: sbi ddrb, 2.
  • Öffne im Fenster I/O Ansicht die Register zum PortB.
  • Bewege mit F11 den gelben Pfeil eine Instruktion weiter und beobachte, ob DDRB.2 gesetzt wird.
  • Bewege mit F11 den gelben Pfeil eine Instruktion weiter und beobachte, ob PORTB.2  gesetzt wird.
  • Pin B.2 ist bisher LOW oder 0 und wird jetzt auf HIGH oder 1 gesetzt.

Die Schleife zwischen wdh: und rjmp wdh wird jetzt beliebig oft durchlaufen; eine an B.2 angeschlossene LED mit Vorwiderstand leuchtet.

In allen folgenden Übungen wird das AVR Tool zur Simulation und als Debugger eingesetzt.

Was man wissen sollte - Nibble, Byte, Word und andere

Einzelne Bits fasst man gerne in Gruppen zusammen und gibt ihnen Namen. Übliche Gruppennamen sind:

Nibble

4 Bit
Byte 8 Bit
Word 16 Bit
Double Word 32 Bit
Quadword 64 Bit

Die Bedeutung der Begriffe Word, Double Word und Quadword ist nicht eindeutig und muss immer im Zusammenhang mit dem benutzten Prozessor gesehen werden. Bei einem 64-Bit Prozessor ist es durchaus üblich, dass ein Word aus 64-Bit besteht.

Die Bezeichnung aus der obigen Tabelle geht auf die 80-er Jahre zurück, als es nur 8- und 16-Bit Prozessoren für den Massenmarkt gab.

5 - BASCOM und Assembler

Der Einstieg in Assembler wird durch BASCOM sehr erleichtert. Wer nicht beim einfachen Abtippen von Programmen stehen bleiben und etwas tiefer in die Abläufe der Controller einsteigen möchte, sollte sich die Zeit nehmen, die hier vorgestellten Übungen intensiv durcharbeiten und dann auf die integrierte Entwicklungsumgebung AVR Studio 4.19 umschwenken.

Im vorherigen Abschnitt 4 wurde gezeigt, wie man sich mit Hilfe eines Debuggers die Ablauffolge in einem Assemblerprogramm mit gleichzeitiger Betrachtung verschiedener Register anzeigen lassen kann. In diesem Abschnitt wird erst einmal gezeigt, wie ein Assemblerprogramm in BASCOM aussehen muss. Dazu greifen wir das kurze Programm aus Abschnitt 4 auf und schauen uns seinen Verlauf in BASCOM an, brennen das Programm in einen ATtiny13A und überprüfen an der Hardware die vorhergesagte Verhaltensweise des Programms.

Einfaches Assemblerprogramm mit LED
Material
  • 1x  GA_BR (Grundausstattung Brenner, siehe Abschnitt 1)
  • 1x  GA_AS (Grundausstattung Anwenderschaltung, siehe Abschnitt 1)
  • 1x  Widerstand, 220 Ohm
  • 1x  LED, rot
  • diverse Steckdrähte

Aufbau der Anwenderschaltung

Abbildung 9 - Schaltungsaufbau für eine blinkende LED.
Einfaches Assemblerprogramm mit LED
Aufgaben
  • Trenne die USB-Verbindung zwischen Brenner und PC.
  • Setze einen ATtiny13A in den Nullkraftsockel des Brenners und stelle die USB-Verbindung zum PC wieder her.
  • Lade das Programm BASCOM, lege ein neues Projekt AVR_Assembler_Teil1 an und speichere es ab.
  • Konfiguriere den Prozessor und den Programmer unter Optionen - Compiler - Chip.
  • Stelle die Taktfrequenz des Prozessors unter Optionen - Compiler - Communication ein.
  • Stelle den Comport, die Baudrate, das Parity, Data- und Stopbits sowie Handshake unter Optionen - Communication ein.
  • Konfiguriere den Programmer unter Optionen - Programmer.
  • Übertrage die eingestellten Daten in den Programmeditor über Optionen - Compiler - Chip und den Button Add to Code.
  • Übertrage das Programm led_0.bas in den BASCOM Editor und speichere es ab.

Das Programm led_0.bas

Abbildung 10 - Programm led_0.bas

Dieses Programm ist identisch zum Assembler-Programm aus Abschnitt 4.

  • Kompiliere das Programm mit F7 oder über das Hauptmenü Programmieren - Compilieren.
  • Wenn kein Fehler angezeigt wurde, brenne das Programm in den Controller mit Programmieren - Zum Chip senden - Programmieren.
  • Entnimm den ATtiny13A aus dem Nullkraft-Sockel und setze ihn in die Anwenderschaltung ein. Lege anschließend eine Spannungsversorgung an und achte dabei auf richtige Polung. Die LED sollte jetzt leuchten.

In der Simulation in Abschnitt 4 wurde bereits gezeigt, dass dieses Programm Pinport B.2 auf HIGH oder 1 setzt und damit eine LED einschaltet.

Wie arbeitet das Programm led_0 ?

Ein Assembler-Programm unter BASCOM beginnt immer mit

  • $asm

und endet mit

  • $end asm

Zwischen diesen beiden Markern muss das Assembler-Programm eingegeben werden.

Das eigentliche Programm besteht aus nur 5 Programmzeilen (Zeilen 16 - 21).

Zeile 16

Sprungadresse Start:, die nie angesprungen wird. Im Prinzip kann diese Zeile weggelassen werden; ich setze sie aus reiner Gewohnheit;-)

Zeile 17

SBI oder Set Bit ist ein sogenanntes Mnemonic für einen Maschinenbefehl. Was diese Instruktion tut, steht im Datenblatt des ATtiny13A unter Kapitel 21: Instruction Set Summary (S. 160ff). Dort findet sich unter dem Abschnitt BIT AND BIT-TEST INSTRUCTIONS

SBI Port, Bit              Setze ein Bit in einem Portregister auf 1

SBI PORTB, 2 setzt das 2. Bit im Register PORTB auf 1.

Befehlsausführungszeit: zwei Clocks (Taktimpulse). Bei 9,6 MHz entspricht das 208,3 ns, bei einem ATtiny mit 1,2 MHz dauert die Ausführung dieses Befehls 1,67 µs oder 1667 ns. Statusregister-Flags sind nicht betroffen.

 

Zeile 19

Die Sprungadresse Wdh: markiert eine Endlosschleife mit den beiden folgenden Befehlszeilen.

 

Zeile 20

SBI PORTB, 2                       Setzt Bit 2 im Register PORTB auf 1.

 

Zeile 21

RJMP (relativ jump) ist ein Rücksprungbefehl zur besagten Adresse wdh. Die genaue Syntax dieses Befehls findet sich ebenfalls im Datenblatt des Controllers:

RJMP k                      führt einen Sprung relativ zur momentanen Adresse aus.

Es wird ein Sprung von k (Offset) relativ zur momentanen Adresse ausgeführt. Der Inhalt des Programmzählers ändert sich um den Wert k + 1, alternativ kann eine Sprungmarke angegeben werden.

Befehlsausführungszeit: zwei Clocks, das entspricht 208,3 ns bei 9,6 MHz oder 1667 ns bei 1,2 MHz. Statusregister-Flags sind nicht betroffen.

6 - Die I/O Ports des ATtiny13

Die Richtung eines Portpins kann von Eingang auf Ausgang geändert werden; die Ausgangstreiber sind stark genug, eine LED direkt anzusteuern und jedem Portpin kann individuell ein Pull-Up Widerstand zugeschaltet werden. Als Bezeichner tauchen in den Datenblättern die Buchstaben "x" für den Buchstaben des angesprochenen Ports und "n" für die Bitposition auf; wir werden sie genau so benutzen.

 

Beispiel

PORTB3         bezeichnet Port B mit der Bitposition 3

PORTxn         bezeichnet Port x mit der Bitposition n

 

Jedem Port werden drei I/O Speicheradressen zugeordnet, jeweils eine für das

  • Data Register - PORTx (read/write)
  • Data Direction Register - DDRx (read/write)
  • Port Input Pins Register - PINx (read only)
  • Das Eingangsregister PINBn zeigt immer den aktuellen Zustand der Pins an. Er wird auch eingelesen, wenn der Pin als Ausgang beschaltet ist.
  • Das Richtungsregister DDRBn legt die Eigenschaften der Ausgangstreiber fest. Bei DDBx = 1 (aktiver Ausgangstreiber) wird der Pegel des entsprechenden Registerbits PORTx auf den Ausgang gelegt.
  • Das Ausgangsregister PORTBn wird bei aktivem Ausgangstreiber entsprechend dem anliegenden Bit gesteuert. Bei inaktivem Ausgangstreiber (0) wird mit einer 1 im Ausgangsregister der Pull-Up aktiviert.

Der Zugriff auf die Register wird durch die folgende Tabelle näher erklärt.

  • Pin n als Eingang oder Ausgang deklarieren

Eingang          DDBn = 0

Ausgang         DDBn = 1

Bit n = 0 weist immer auf einen Eingang, Bit n = 1 immer auf einen Ausgang hin.

---------------------------------------------------------------------------------------------

  • Pull-Up Widerstand am Pin n einschalten

Widerstand einschalten         DDBn = 0 UND PORTBn = 1

Widerstand ausschalten        DDBn = 0 UND PORTBn = 0

                                               oder PBn wird als Output deklariert.

----------------------------------------------------------------------------------------------

  • PBn auf HIGH oder LOW legen

PBn auf HIGH setzen            DDBn = 1 UND PORTBn = 1

PBn auf LOW setzen             DDBn = 1 UND PORTBn = 0

----------------------------------------------------------------------------------------------

 

Setzt man in einem PINBn-Register eine 1, führt das zu einem Umschalten des Zustandes im korrespondierenden Bit des Datenregisters PORTBn, völlig unabhängig vom Wert im Register DDRBn.

Mit Hilfe des kleinen Programms led_1.bas lässt sich das schnell nachweisen. Es ist gegenüber dem Programm led_0.bas in Zeile 20 abgeändert worden. Compiliere zunächst das Programm mit F7, schalte den Simulator ein und gehe anschließend Instruktion für Instruktion durch das Programm.

Abbildung 11 - Betrachtung einzelner I/O Register im Simulator. Alle Registerinhalte sind zum Start des Programms 0.

 Das Augenmerk ist auf die drei Register DDRB, PINB und PORTB gerichtet, in denen mit dem Start der Simulation die Werte 00 stehen. Mit Ausführung der Instruktion SBI DDRB, 2 in Programmzeile 17 wird in DDRB der Wert 4 geschrieben.

Abbildung 12 - Bit 2 im DDRB-Register ist gesetzt.

Im folgenden Schritt wird mit SBI PORTB, 2 in PB.2 eine 1 geschrieben.

Abbildung 13 - Bit 2 im PORTB-Register ist gesetzt.

Wiederholt man das Ganze noch einmal, tauscht aber in Programmzeile 17 vorher SBI durch CBI (clear bit) aus, verhält sich das Programm genau wie vorher. Die Einstellung von DDRB hat keinen Einfluss auf das Verhalten von PORTB.2 oder allgemein von PORTB.n.

Warum steht eine 04 bei PORTB und DDRB statt einer 01?

SBI DDRB, 2 bedeutet, im Register DDRB wird an der Bitposition 2 eine 1 geschrieben.

Wird in das PortB.2 Bit eine 1 geschrieben, dann befindet sich dieses Bit an der 3. Stelle einer 8-Bit Zahl. Die binäre Zahl 0b00000100 entspricht der Zahl 4 im 10-er System und ebenso der Zahl 4 im 16-er System. Es ist dieser Wert 4, der vom Simulator als Registerinhalt angezeigt wird.

 

Umschalten zwischen INPUT und OUTPUT

Das Umschalten von INPUT zu OUTPUT ist nicht immer unproblematisch. Der Hersteller ATMEL gibt dazu in seinen Datenblättern entsprechende Hinweise, wo Probleme auftauchen können und wie man sie tunlichst umgeht.

  • Hi-Z nach Output HIGH

Wird von einem Hi-Z Zustand (DDBn = PORTBn = 0 ODER DDBn = 0 UND PORTBn = 1) zu einem Output HIGH (DDBn = PORTBn = 1) gewechselt, sollte das immer über einen Zwischenzustand von entweder DDBn = 0 UND PORTBn = 1 (Pull-Up Widerstand EIN) ODER DDBn = 1 UND PORTBn = 0 (Output LOW) geschehen.

 

  • Input mit Pull-Up nach Output LOW

Das gleiche Problem tritt bei einem Übergang von einem Input mit Pull-Up zu einem Output LOW auf. In diesem Fall sollte man als Zwischenschritt entweder DDBn = PORTBn = 0 (Hi-Z) oder DDBn = PORTBn = 1 (Output HIGH) wählen.

 

Was steht eigentlich in der Datei attiny13a.dat?

Zu Beginn des kleinen Programms led_0.bas wird mit $regfile = "attiny13a.dat" eine Datei aufgerufen. Den Inhalt dieser Datei schauen wir uns etwas genauer an, dazu muss sie mit  einem beliebigen Editor geöffnet werden.

Irgendwo im ersten Drittel der Datei finden sich zum Beispiel die folgenden Einträge

Abbildung 14 - Auszug aus der Datei ATtiny13A.DAT.

aus denen man erahnen kann, welche Arbeit sie uns bei der Erstellung eines Assemblerprogramms bereits abgenommen hat. Diese *.DAT Datei enthält alle notwendigen Voreinstellungen und Namenszuweisungen, die ein Assemblerprogramm später lesbar machen. Mit

  • PORTB = $18

wird die Zuweisung der I/O Adresse $18 zum Wort PORTB vorgenommen. Mit gleichem Verfahren werden die anderen I/O Adressen, DDRB und PINB den entsprechenden Portregisternamen zugewiesen. Statt nach den Adressen für einen bestimmten I/O Port zu suchen, muss nur sein Name, den man sich leichter merken kann, eingegeben werden. Den Rest erledigt die entsprechende *.DAT Datei für uns, die es zu jedem von uns benutzten Controller gibt.

7 - Eine LED blinkt

In diesem Abschnitt werden wir das neue Wissen weiter vertiefen. In einer ersten Übung wird eine LED mit Vorwiderstand anfangen zu blinken. Die Schwierigkeit in dieser einfachen Schaltung besteht darin, dass zwischen dem Ein- und Ausschalten der LED eine Pause von einigen 100 ms eingebaut werden muss.

  • Schreibe ein Programm, das eine LED ein- und ausschaltet. Die LED ist an PB2 (Pin 7) mit einem Vorwiderstand, angeschlossen.
Blinkende LED
Material
  • 1x  GA_BR (Grundausstattung Brenner, siehe Abschnitt 1)
  • 1x  GA_AS (Grundausstattung Anwenderschaltung, siehe Abschnitt 1)
  • 1x  Widerstand, 220 Ohm
  • 1x  LED, rot
  • diverse Steckdrähte

Schaltungsaufbau

Abbildung 15 - Schaltungsaufbau mit einer LED an PB2.
Abbildung 15a - Schaltskizze "Blinkende LED"
Blinkende LED
Aufgaben
  • Baue auf einem Steckbrett die Schaltung nach Schaltskizze bzw. Verdrahtungsplan auf. Schließe die Schaltung noch nicht an eine Energiequelle an.
  • Trenne die USB-Verbindung zwischen Brenner und PC.
  • Setze einen ATtiny13A in den Nullkraftsockel des Brenners und stelle die USB-Verbindung zum PC wieder her.
  • Lade das Programm BASCOM, öffne das Projekt AVR_Assembler_Teil1 und speichere das leere Blatt unter dem neuen Namen led_ue1 ab. Die alten Einstellungen des Programmers aus der vorherigen Übung aus Abschnitt 2 sollten noch aktuell sein.
  • Übertrage das Programm led_1_blinker.bas in den BASCOM Editor und speichere es ab.
  • Kompiliere das Programm (F7) und überprüfe, ob es Fehlermeldungen gibt. Wenn nicht, wurde alles richtig gemacht.
  • Setze den ATtiny13A in die Schaltung auf dem Steckbrett ein und lege anschließend die Versorgungsspannung an.
  • Überprüfe, ob die LED nacheinander ein- und wieder ausgeschaltet wird.

Das Programm led_1_blinker.bas

Abbildung 16 - Programm led_1_blinker.bas

Wie arbeitet das Programm led_1_blinker.bas?

Einige Elemente aus dem Quellcode sind uns bereits bekannt. Aber beginnen wir von vorne. Das Assemblerprogramm startet nach dem Marker $asm in Programmzeile 15.

 

Zeile 17

SBI DDRB, 2 Setzt Bit 2 im DDRB-Register auf 1. 2 CLK

Zeile 19

Wdh:

Einsprungstelle für eine Schleife

0 CLK

Zeile 20

SBI PORTB, 2

Setzt Bit 2 im PORTB-Register. Als Folge davon geht

die LED an; sie ist mit ihrem Vorwiderstand gegen

Masse geschaltet.

2 CLK

Zeile 21

CBI PORTB, 2

Setzt Bit 2 im PORTB-Register auf 0 zurück. Als Folge

davon geht die LED aus.

2 CLK

Zeile 22

RJMP Wdh

Springt zurück an die Marke Wdh: und alles beginnt von

vorne.

2 CLK

Der Vorgang: LED ein - LED aus läuft in diesem Programm sehr schnell ab; es werden gerade mal 6 CLKs (Taktzyklen) benötigt. Bei einer voreingestellten Taktfrequenz von 9,6 MHz und gesetztem Fusebit E (Divide by 8) ergibt das

1,2 MHz / 6 = 0,2 MHz oder 200 kHz.

Der Ein-/Ausschaltvorgang der LED läuft 200.000-mal pro Sekunde ab und das ist für unser Auge einfach zu schnell.

Das folgende Oszillogramm wurde am I/O PortB2 des Controllers aufgenommen und zeigt die Ein-/Aus-Schaltvorgänge. Gut zu erkennen sind:

Abbildung 17 - Oszillogramm am PORTB2 des ATtiny13A. Aufgenommen mit PicoScope2000.

Die gemessene Schaltfrequenz liegt bei ca. 187 kHz

Der HIGH-Zustand dauert nur halb so lange wie der LOW-Zustand. Dem Oszillogramm kann man entnehmen:

  • LOW-Zustand: ca. 3,5 µs
  • HIGH-Zustand: ca. 1,8 µs

Ein Blick in das Assembler-Programm klärt diesen Unterschied. Nach SBI PORTB, 2 - LED geht AN (2 CLK) folgt CBI PORTB, 2 - LED geht AUS (2 CLK) gefolgt von einem RJMP wdh - LED immer noch aus (2 CLK). Insgesamt 4 Taktzyklen bleibt die LED dunkel, 2 Taktzyklen hell - schade, dass wir das der LED nicht angesehen haben;)

 

Wer tiefer in die Assemblerprogrammierung einsteigen möchte, sollte sich den Kapiteln AVR Assembler - Teil x zuwenden. Es wird ausschließlich mit der Programmieroberfläche AVR Studio und der Sprache Assembler gearbeitet. Interessiert? Dann geht es hier weiter zu AVR Assembler - Teil 1.

Kommentar schreiben

Kommentare

  • olaf (Sonntag, 10. Dezember 2017 08:35)

    wow...die mit Abstand beste Site, die ich bisher zu diesem Thema gesehen habe :-))
    Vielen Dank dafür. Hilft super beim Erklären!!

  • David Eisenblätter (Sonntag, 11. Februar 2018 13:38)

    Sehr schön erklärt, und zufällig heute, wo ich nochmal nach einer detailierten Gedankenstütze diesbezüglich gesucht habe!

    Vielen vielen Dank!

    David.

Bitte geben Sie den Code ein
* Pflichtfelder
Druckversion Druckversion | Sitemap
© Reinhard Rahner - Gettorf