Forum: Mikrocontroller und Digitale Elektronik AVR-Studio und Stack


von Phip (Gast)


Lesenswert?

Hallo zusammen,

Ich hab' ein Prog für die Ansteuerung eines LED-Displays an meinen
ATmega8515 geschrieben. Dieses hat allerdings noch einige Bugs, weshalb
ich es gerne Schritt für Schritt mit dem Debugger durchlaufen lassen
möchte.
Nun gibt's da aber ein Problem mit dem Stack:
Meine Routine zum Initialisieren des Stackpointers
1
        ldi temp, LOW(RAMEND)
2
        out SPL, temp
3
        ldi temp, HIGH(RAMEND)
4
        out SPH, temp
Das tut auch richtig, im Processor-Fenster wird für den Stackpointer
0x025F angezeigt. Sobald ich nun allerdings zu einem Aufruf einer
Subroutine komme, passiert Folgendes:
An der Adresse im RAM, auf die der Stackpointer zeigt, passiert nichts,
dort bleibt einfach 0000 stehen. Logischerweise geht das Prog dann
natürlich dort weiter, wo .org 0x00 steht, also ganz am Anfang. Warum
funktioniert das nicht? Hattet oder habt ihr dieses Problem auch? Ich
glaube, es funktioniert, wenn man keine Interrupts verwendet, also
keine .org-Anweisung vorkommt.
Noch etwas: Auch der normale Zugriff auf den Stack mit push und pop
funktioniert nicht richtig. Der Wert wird zwar ins RAM geschrieben und
von dort auch wieder richtig gelesen, aber beim poppen nicht mehr
gelöscht :(

Kann mir jemand helfen? Der Debugger wär' doch so praktisch!

Vielen Dank im Voraus!

PS: Bei rcall wird der Stackpointer schon verändert, er zeigt dann also
auf die Adresse 2 Byte vor dem RAMende. Nur wird dort eben nichts
reingeschrieben :(

von Thomas (Gast)


Lesenswert?

Ich habe bis jetzt noch keinen Prozessor gesehen, der bei
POP-Operationen den Wert im RAM löscht. Wozu auch.

von dave (Gast)


Lesenswert?

Ich mach mal Stichwörter:
 - RAMgröße (nach Datenblatt) M8515: "512 Bytes Internal SRAM"
 - 512 (dez) = 0x200 (vergleich mal mit deinem Wert)


dave

von ...HanneS... (Gast)


Lesenswert?

Naja, SRAM fängt aber erst bei $60 ($100 beim 128er) an, drunter sind
schließlich noch Register und I/O gemappt. Also geht er auch $60 ($100)
Zellen weiter...

von dave (Gast)


Lesenswert?

Habs auch grad gemerkt.. lol... sorry.

dave

von Phip (Gast)


Lesenswert?

Ok, das mit dem Löschen ist vielleicht nicht nötig. Aber darum funzt der
Rücksprung halt einfach immer noch nicht :(

von Santa Klaus (Gast)


Lesenswert?

Wenn der nicht funzt, dann liegt's an Deinem Programm. Guck mal, ob in
der Subroutine "push"- und "pop"-Befehle stehen und check dann, ob
auch jeder "push" sein "pop"-Pendant hat.  Gibt es Verzweigungen in
der Subroutine?  Wird bei einer Verzweigung vielleicht ein notwendiges
"pop" übersprungen?  Das könnte z. B. die Ursache für Dein Problem
sein.

Du kannst Deinem Bug übrigens auch einfach dadurch auf die Schliche
kommen, indem Du jeden_ _einzelnen_ _Schritt im Debugger in
"mühevoller Kleinarbeit" beobachtest.  Dabei mußt Du insbesondere den
Stackpointer kontrollieren, d. h. Du mußt zu jedem Zeitpunkt darüber
Bescheid wissen, wo er hinzeigt.  Du wirst dann feststellen, daß er an
irgendeinem Programmpunkt wo hinzeigt, wo er nicht hinzeigen soll.  In
diesem Moment weißt Du die Stelle, wo der Bug in Deinem Programm
steckt.  Probier's aus - viel Erfolg.

PS: [Ironie] Wenn mal ein selbstgeschriebenes Programm nicht das tut,
was es soll, dann liegt's stets am Compiler... ;-) [/Ironie]

von Horst (Gast)


Lesenswert?

Mal ne frage: soll man bei 16 Bit Angelegenheiten nicht immer erst das
High Byte schreiben? Hatte mal nen Ähnlichen Fall aber mit den Timer
Variablen.

Grüße Horst

von dave (Gast)


Lesenswert?

Ja, da gibts nen paar Register, aber nicht der Stackpointer. Sonst würde
bei mir auch nix laufen. Timer ist nen Beispiel.


@Phip
Kannste vielleicht noch etwas Zeug rausrücken? Welches AVR-Studio isses
denn?

dave

von Andi-H (Gast)


Lesenswert?

Hallo,

ich misch' mich da mal kurz ein ;-) Hab kürzlich ein ähnliches
Phänomen gehabt, dass beim Rücksprung aus der Int-Routine wieder zum
Anfang des Programms gesprungen wurde. Bei mir lags daran, dass ich von
einem andren (kleineren) AVR den Code implementiert habe und ich dabei
den Stackpointer dabei vergessen hatte... Das ist bei Dir ja nicht der
Fall. Aber ich würde erstmal so als Tip geben: Überprüf nochmal, ob Du
den Debugger auch für den mega8515 eingestellt hast, vielleicht klappts
mit dem Code ja richtig, nur der Debugger ist falsch eingestellt? Hast
Du auch am Anfang des Codes die richtige Datei "included"? Nicht das
hier schon das "Ramend" falsch eingebunden wird...

ciao, Andi.

von Phip (Gast)


Angehängte Dateien:

Lesenswert?

Nunja, beim Sim hab' ich das eingestellt, was ich so gefunden hab'.
Der 8515 hat ja eigentlich ein 512 Byte RAM, aber RAMEND zeigt auf
0x025F, da, wie schon gesagt, das RAM noch etwas grösser für den
IO-Bereich und so sein muss. Ich hab' das Programm schon Schritt für
Schritt durchlaufen, aber wie gesagt, an einem push oder pop kann's
nicht liegen, da schon der Aufruf der Prozedur seinen Zweck verfehlt.
Der Stackpointer wandert zwar um 2 Byte nach vorne, aber der
entsprechende Speicherplatz wird nicht verändert...

Auf'm Screenshot seht ihr das ganze Prog im Simulator mit den
Einstellungen desselben. Hier hab' ich den Prozeduraufruf schonmal
durchlaufen und wie ihr rechts im Data-Fenster seht, ist im RAM einfach
alles 0. Das einzelne F kommt von einem push in der Prozedur, das
allerdings nichts zur Sache tut.

Das Problem im Code, das ich ursprünglich gesucht hab', hab' ich
jetzt behoben, aber ein funktionierender Debugger wär' halt schon
schön.

Danke schonmal für die Hilfe!

von ...HanneS... (Gast)


Lesenswert?

512 Byte SRAM geht von $60 bis $25f... Was ist da falsch?????

- $00...$1f : 32 Byte Register
- $20...$5f : 64 Byte I/O-Bereich
- $60...$25f: 512 Byte SRAM

Wo ist das Problem???

...

von Santa Klaus (Gast)


Lesenswert?

Hi,

>an einem push oder pop kann's
>nicht liegen, da schon der Aufruf der Prozedur seinen Zweck verfehlt.
>Der Stackpointer wandert zwar um 2 Byte nach vorne, aber der
>entsprechende Speicherplatz wird nicht verändert...

dann ist das wirklich sehr mysteriös. Trotzdem bleib ich dabei: Der
Simulator selbst ist nicht fehlerhaft, auch wenn er sich hier aufgrund
von was auch immer fehlerhaft verhält. Ich vermute, daß es an
irgendeiner "Mißkonfiguration" liegt, d. h. an irgendetwas, das Du
(unwissentlich?) falsch eingestellt hast.

Poste mal Dein Programm hier, damit ich es bei mir im Simulator laufen
lassen kann.  Wenn ich den Fehler reproduzieren kann, werde ich ihm den
Garaus machen - versprochen.

von Phip (Gast)


Lesenswert?

Also, hier der gesamte Code:
Er ist zur Ansteuerung zweier 7-Segment-LED-Anzeigen an PortC. Die 7
Segmente werden über einen Vorwiderstand an den Port angeschlossen. Die
beiden Plus werden seperat über je einen Transistor von den Bits 0 und 1
von PortE gesteuert. Es funktioniert nun eigentlich alles, bis eben auf
das richtige debugging...
Achja: Ausgegeben wird jeweils die Zahl im Hex-Format, die gerade über
die RS232 reinkam. Da hab' ich auch gemerkt, dass ich dort nix
gescheites kriege... (Siehe anderen Thread).

Code:


.include "m8515def.inc"

.def temp = R16
.equ CLOCK = 12000000
.equ BAUD = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1


;Display.asm
************************************************************************ 
**********************************
.def LED_Value_Hex = r20    ;Hexadezimale Anzeige
.def LED_Delay_ValueH = r30    ;Zeit zum Warten (High und Low von
LED_DelayXXms)
.def LED_Delay_ValueL = r29
.def LED_Delay_ValueM = r28    ;Multiplikator für's warten
.def LED_Temp = r16        ;Temporäre Register
.def LED_Temp2 = r17
.def LED_Delay_SetLed = r18    ;= 1, wenn beim Warten ebenfalls 
angezeigt
werden soll

.equ LED_Delay1ms = 1000    ;1ms warten = 12000 Zyklen nichts tun
.equ LED_Delay5ms = 5000    ;5ms warten = 60000 Zyklen nichts tun
.equ LED_Delay10ms = 10000    ;10ms warten = 120000 Zyklen nichts tun
.equ LED_Delay30ms = 30000    ;30ms warten = 360000 Zyklen nichts tun
.equ LED_Delay60ms = 60000    ;60ms warten = 720000 Zyklen nichts tun

.equ LED_Display_0 = 0b00111111
.equ LED_Display_1 = 0b00000110
.equ LED_Display_2 = 0b01011011
.equ LED_Display_3 = 0b01001111
.equ LED_Display_4 = 0b01100110
.equ LED_Display_5 = 0b01101101
.equ LED_Display_6 = 0b01111101
.equ LED_Display_7 = 0b00000111
.equ LED_Display_8 = 0b01111111
.equ LED_Display_9 = 0b01101111
.equ LED_Display_A = 0b01110111
.equ LED_Display_B = 0b01111100
.equ LED_Display_C = 0b00111001
.equ LED_Display_D = 0b01011110
.equ LED_Display_E = 0b01111001
.equ LED_Display_F = 0b01110001
;*********************************************************************** 
***********************************************





.org 0x00
        rjmp main

.org URXCaddr                             ; Interruptvektor für
UART-Empfang
        rjmp int_rxc

; Hauptprogramm
main:
        ldi temp, LOW(RAMEND)
        out SPL, temp
        ldi temp, HIGH(RAMEND)
        out SPH, temp

        ; Baudrate einstellen
        ldi temp, LOW(UBRRVAL)
        out UBRRL, temp
        ldi temp, HIGH(UBRRVAL)
        out UBRRH, temp

        ; Frame-Format: 8 Bit
        ldi temp, (0b01<<URSEL)|(0b11<<UCSZ0)  ;= 0b10000000 Or 0b110
(URSEL = 7, UCSZ0 = 1)
        out UCSRC, temp

        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren

        ldi temp, 0x0F
        out DDRA, temp

        rcall LED_Initialize
        rcall LED_Test

        sei                               ; Interrupts global
aktivieren

    loop:
      rcall LED_Out_Hex

      rcall lED_Delay_10ms
    rjmp loop                         ; Endlosschleife


; Interruptroutine: wird ausgeführt sobald ein Byte über das UART
empfangen wurde
int_rxc:
    push temp
    push r17

        in temp, UDR

        ldi r17, 0xFF

    sbis PINA, 4
    eor temp, r17

    sbis PINA, 5
    swap temp

    sbis PINA, 6
    rol temp

    sbis PINA, 7
    ror temp

    mov LED_Value_Hex, temp

        pop r17
        pop temp
reti                                    ; Interrupt beenden








;Display.asm
************************************************************************ 
**********************************








LED_Initialize:          ;Anzeige initialisieren

  push LED_Temp        ;Register speichern

  ldi LED_Temp, 0xFF
  out DDRC, LED_Temp      ;Richtungsregister konfigurieren: PortC =
Ausgang

  ldi LED_Temp, 0b00000011
  out DDRE, LED_Temp      ;Bit 0 und 1 von PortE sind Ausgänge

  ldi LED_Temp, 0xFF
  out PORTC, LED_Temp      ;Anzeige ausschalten

  ldi LED_Temp, 0x01
  out PORTE, LED_Temp

  pop LED_Temp

;  rcall LED_Test        ;Displaytest
;
;  ldi LED_Temp, 0xFF
;  ldi LED_Delay_SetLed, 1    ;Beim Warten auch ausgeben!
;  ldi LED_Value_Hex, 0    ;Bei 0 zu Zählen anfangen
;
;  LED_Ini_Loop_:
;
;    rcall LED_Delay_180ms  ;180ms warten
;
;    inc LED_Value_Hex
;
;    sbis PINA, 4
;    ldi LED_Value_Hex, 0xFF
;
;    rcall LED_Out_Hex    ;Wert ausgeben
;
;    cpi LED_Value_Hex, 0xFF
;    brne LED_Ini_Loop_
;
;    sbic PINA, 4
;    eor LED_Value_Hex, LED_Value_Hex
;
;  rjmp LED_Ini_Loop_      ;Endlosschleife

ret



LED_Test:            ;Einen Displaytest durchführen

  push LED_Temp        ;Register speichern
  push LED_Temp2
  push r19

  ldi LED_Delay_SetLed, 0    ;Beim Warten nicht ausgeben!

  ldi LED_Temp, 1        ;0x00000001 ins Register laden
  ldi r19, 0xFF

  ;Erste Stelle testen
  ldi LED_Temp2, 0b10
  out PORTE, LED_Temp2

  LED_Test_Loop_:

    eor LED_Temp, r19    ;Register umkehren
    out PORTC, LED_Temp    ;Wert ausgeben
    eor LED_Temp, r19    ;Register wieder zurückkehren

    sbrc LED_Temp, 7    ;Ist das 7. Bit gesetzt?
    rjmp LED_Test_2nd_    ;Ja, Schleife verlassen

    lsl LED_Temp      ;Ein Bit nach links schieben

    rcall LED_Delay_120ms  ;120ms warten

  rjmp LED_Test_Loop_

  LED_Test_2nd_:

  rcall LED_Delay_120ms    ;120ms warten


  ldi LED_Temp, 1

  ;Zweite Stelle testen
  ldi LED_Temp2, 0b01
  out PORTE, LED_Temp2

  LED_Test_Loop2_:

    eor LED_Temp, r19    ;Register umkehren
    out PORTC, LED_Temp    ;Wert ausgeben
    eor LED_Temp, r19    ;Register wieder zurückkehren

    sbrc LED_Temp, 7    ;Ist das 7. Bit gesetzt?
    rjmp LED_Test_End_    ;Ja, Schleife verlassen

    lsl LED_Temp      ;Ein Bit nach links schieben

    rcall LED_Delay_120ms  ;120ms warten

  rjmp LED_Test_Loop2_


  LED_Test_End_:


  pop r19
  pop LED_Temp2
  pop LED_Temp

ret


LED_Out_Hex:          ;Den Hex-Wert in LED_Value_Hex anzeigen

  push LED_Temp        ;Register speichern
  push LED_Temp2

  ;Von der einen auf die andere Stelle umschalten
  in LED_Temp, PORTE

  ;Ist da vielleicht 0b11 oder 0b00 drin?
  cpi LED_Temp, 0
  breq LED_Out_Hex_SetE_
  cpi LED_Temp, 3
  brsh LED_Out_Hex_SetE_
  rjmp LED_Out_Hex_Continue4_

  LED_Out_Hex_SetE_:
    ldi LED_Temp, 1    ;Ja, auf 0b01 setzen

  LED_Out_Hex_Continue4_:

  sbrs LED_Temp, 0
  rjmp LED_Out_Hex_SR_
    lsl LED_Temp
    rjmp LED_Out_Hex_Continue_
  LED_Out_Hex_SR_:
    lsr LED_Temp
  LED_Out_Hex_Continue_:

  out PORTE, LED_Temp

  ;Den auszugebenden Wert für die aktuelle Anzeige in LED_Temp laden
  mov LED_Temp, LED_Value_Hex
  sbis PORTE, 0
  rjmp LED_Out_Hex_Continue2_
    swap LED_Temp
  LED_Out_Hex_Continue2_:
  andi LED_Temp, 0x0F


  cpi LED_Temp, 0x00
  breq LED_Out_Hex_0x00_
  cpi LED_Temp, 0x01
  breq LED_Out_Hex_0x01_
  cpi LED_Temp, 0x02
  breq LED_Out_Hex_0x02_
  cpi LED_Temp, 0x03
  breq LED_Out_Hex_0x03_
  cpi LED_Temp, 0x04
  breq LED_Out_Hex_0x04_
  cpi LED_Temp, 0x05
  breq LED_Out_Hex_0x05_
  cpi LED_Temp, 0x06
  breq LED_Out_Hex_0x06_
  cpi LED_Temp, 0x07
  breq LED_Out_Hex_0x07_
  cpi LED_Temp, 0x08
  breq LED_Out_Hex_0x08_
  cpi LED_Temp, 0x09
  breq LED_Out_Hex_0x09_
  cpi LED_Temp, 0x0A
  breq LED_Out_Hex_0x0A_
  cpi LED_Temp, 0x0B
  breq LED_Out_Hex_0x0B_
  cpi LED_Temp, 0x0C
  breq LED_Out_Hex_0x0C_
  cpi LED_Temp, 0x0D
  breq LED_Out_Hex_0x0D_
  cpi LED_Temp, 0x0E
  breq LED_Out_Hex_0x0E_
  cpi LED_Temp, 0x0F
  breq LED_Out_Hex_0x0F_

  LED_Out_Hex_0x00_:
  ldi LED_Temp2, LED_Display_0
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x01_:
  ldi LED_Temp2, LED_Display_1
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x02_:
  ldi LED_Temp2, LED_Display_2
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x03_:
  ldi LED_Temp2, LED_Display_3
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x04_:
  ldi LED_Temp2, LED_Display_4
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x05_:
  ldi LED_Temp2, LED_Display_5
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x06_:
  ldi LED_Temp2, LED_Display_6
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x07_:
  ldi LED_Temp2, LED_Display_7
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x08_:
  ldi LED_Temp2, LED_Display_8
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x09_:
  ldi LED_Temp2, LED_Display_9
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x0A_:
  ldi LED_Temp2, LED_Display_A
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x0B_:
  ldi LED_Temp2, LED_Display_B
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x0C_:
  ldi LED_Temp2, LED_Display_C
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x0D_:
  ldi LED_Temp2, LED_Display_D
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x0E_:
  ldi LED_Temp2, LED_Display_E
  rjmp LED_Out_Hex_Continue3_
  LED_Out_Hex_0x0F_:
  ldi LED_Temp2, LED_Display_F

  LED_Out_Hex_Continue3_:


  ldi LED_Temp, 0xFF        ;Wert umkehren (0 = Ein, 1 = Aus)
  eor LED_Temp2, LED_Temp

  out PORTC, LED_Temp2      ;Wert ausgeben

  pop LED_Temp2
  pop LED_Temp

ret




LED_Delay_180ms:
  ldi LED_Delay_ValueH, HIGH(LED_Delay60ms)
  ldi LED_Delay_ValueL, LOW(LED_Delay60ms)
  ldi LED_Delay_ValueM, 3

  rcall LED_Delay
ret

LED_Delay_120ms:
  ldi LED_Delay_ValueH, HIGH(LED_Delay60ms)
  ldi LED_Delay_ValueL, LOW(LED_Delay60ms)
  ldi LED_Delay_ValueM, 2

  rcall LED_Delay
ret

LED_Delay_10ms:
  ldi LED_Delay_ValueH, HIGH(LED_Delay10ms)
  ldi LED_Delay_ValueL, LOW(LED_Delay10ms)
  ldi LED_Delay_ValueM, 1

  rcall LED_Delay
ret


LED_Delay:            ;Eine bestimmte Zeit warten (Zeit in 
LED_Delay_Value
wird gewartet)

  push LED_Temp        ;Register speichern
  push LED_Temp2

  mov LED_Temp, LED_Delay_ValueL  ;Low-Value speichern
  mov LED_Temp2, LED_Delay_ValueH ;High-Value speichern

  LED_Delay_LoopM_:

    mov LED_Delay_ValueH, LED_Temp2    ;Zählregister wieder füllen

    LED_Delay_Loop_:

      mov LED_Delay_ValueL, LED_Temp  ;Zählregister wieder füllen

      LED_Delay_Loop2_:

        dec LED_Delay_ValueL    ;Register dekrementieren (- 1)

        nop
        nop
        nop

        nop
        nop
        nop
        nop
        nop
        nop

        cpi LED_Delay_ValueL, 0    ;Ist es 0?

        brne LED_Delay_Loop2_    ;Wenn nicht, dann Schleife



      dec LED_Delay_ValueH      ;Register dekrementieren (- 1)

      cpi LED_Delay_ValueH, 0      ;Ist es 0?

      brne LED_Delay_Loop_      ;Wenn nicht, dann Schleife


    dec LED_Delay_ValueM      ;Register dekrementieren (- 1)

    cpi LED_Delay_ValueM, 0      ;Ist es 0?

    brne LED_Delay_LoopM_      ;Wenn nicht, dann Schleife


  pop LED_Temp2
  pop LED_Temp

ret                ;Prozedurende







Danke schonmal für eure Hilfe!

von Phip (Gast)


Lesenswert?

@Admins:
Sorry wegen dem vielen Code, ich hab' übersehen, dass ich den als
Anhang schicken sollte :$

von dave (Gast)


Lesenswert?

Auweia...

Fangen wir mal hinten an:
 - DEC setzt, sobald das Register 0 wird, das gleiche wie CPI 0, also
lass das CPI weg und setzt das DEC immer vors BRNE und feddich
 - Wenn du da in dem riesen CPI Ding deine Leds ein/ausschaltest, da
nimmste nen Table, das auf einen Speicherplatz im Flash zeigt. An dem
hast du die Werte für die LEDs hinterlegt, im Tutorial hier ist sowas
angedeutet. Du lädst ind ZH:ZL den Anfang der Tabelle (WICHTIG: Adresse
mal 2 nehmen, wegen Byte/Word) und addierst dann den Wert dazu und liest
einfach mit LPM den vorher mit ".db 0b011101, 0b11011"
eingespeicherten Wert aus. Immer 2 Bytes in eine Zeile.

Kannste bitte einfach nochmal überprüfen, ob du aus Versehen den
ATMEGA85DREI5 oder nen 90er eingestellt hast... und stell nicht auf
CUSTOM, sondern hol dir das neue Studio, wenn das noch das alte ist.

dave

von ...HanneS... (Gast)


Lesenswert?

Übrigens:
In der Befehlsliste am Ende des Datenblattes kann man auch nachsehen,
welche Befehle welche Flags (im SREG) beeiflussen.

...

von Phip (Gast)


Lesenswert?

Wenn ich gewusst hätte, dass es ein neueres AVR-Studio gibt... Könnte da
vielleicht mal jemand den Link im Tut erneuern?

Jetzt geht's jedenfall! freu

Danke an alle, die daran beteiligt waren!

:)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.