hallo, versuch verzweifelt die usart1 vom Mega128 inbetrieb zunehmen es sollte erstmal nur ein text an den pc geschickt werden, aber es kommt nur wirres zeug an. viellecht könnte mir jemand weiterhelfen danke
hallo, habe soeben noch mal die FUSES nachgeschaut, die Fuses Jtag und 103 modus sind deaktiviert, mega128 läuft mit 14,745600MHz Quarz, könnte mir denn vielleicht jemand weiterhelfen danke
Hilft das ? /***************************************************** This program was produced by the CodeWizardAVR V1.24.8 Standard Automatic Program Generator © Copyright 1998-2006 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : mega128_2uart Version : Date : 24.11.2007 Author : Winfried Jaeckel Company : Deviltronic Comments: Chip type : ATmega128 Program type : Application Clock frequency : 14,745600 MHz Memory model : Small External SRAM size : 0 Data Stack size : 1024 *****************************************************/ #include <mega128.h> #define RXB8 1 #define TXB8 0 #define UPE 2 #define OVR 3 #define FE 4 #define UDRE 5 #define RXC 7 #define FRAMING_ERROR (1<<FE) #define PARITY_ERROR (1<<UPE) #define DATA_OVERRUN (1<<OVR) #define DATA_REGISTER_EMPTY (1<<UDRE) #define RX_COMPLETE (1<<RXC) void UART1_Write_Strf (flash char str [] ) { while ( *str ) { putchar1(*str++); } // USART0 Receiver buffer #define RX_BUFFER_SIZE0 8 char rx_buffer0[RX_BUFFER_SIZE0]; #if RX_BUFFER_SIZE0<256 unsigned char rx_wr_index0,rx_rd_index0,rx_counter0; #else unsigned int rx_wr_index0,rx_rd_index0,rx_counter0; #endif // This flag is set on USART0 Receiver buffer overflow bit rx_buffer_overflow0; // USART0 Receiver interrupt service routineputchar1(0xa);putchar1(0xd);UART1_Write_Strf(" \n\r") interrupt [USART0_RXC] void usart0_rx_isr(void) { char status,data; status=UCSR0A; data=UDR0; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) { rx_buffer0[rx_wr_index0]=data; if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0; if (++rx_counter0 == RX_BUFFER_SIZE0) { rx_counter0=0; rx_buffer_overflow0=1; }; }; } #ifndef DEBUG_TERMINAL_IO // Get a character from the USART0 Receiver buffer #define ALTERNATE_GETCHAR #pragma used+ char getchar(void) { char data; while (rx_counter0==0); data=rx_buffer0[rx_rd_index0]; if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0; #asm("cli") --rx_counter0; #asm("sei") return data; } #pragma used- #endif // USART0 Transmitter buffer #define TX_BUFFER_SIZE0 8 char tx_buffer0[TX_BUFFER_SIZE0]; #if TX_BUFFER_SIZE0<256 unsigned char tx_wr_index0,tx_rd_index0,tx_counter0; #else unsigned int tx_wr_index0,tx_rd_index0,tx_counter0; #endif // USART0 Transmitter interrupt service routine interrupt [USART0_TXC] void usart0_tx_isr(void) { if (tx_counter0) { --tx_counter0; UDR0=tx_buffer0[tx_rd_index0]; if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0; }; } #ifndef DEBUG_TERMINAL_IO // Write a character to the USART0 Transmitter buffer #define ALTERNATE_PUTCHAR #pragma used+ void putchar(char c) { while (tx_counter0 == TX_BUFFER_SIZE0); #asm("cli") if (tx_counter0 || ((UCSR0A & DATA_REGISTER_EMPTY)==0)) { tx_buffer0[tx_wr_index0]=c; if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0; ++tx_counter0; } else UDR0=c; #asm("sei") } #pragma used- #endif // USART1 Receiver buffer #define RX_BUFFER_SIZE1 8 char rx_buffer1[RX_BUFFER_SIZE1]; #if RX_BUFFER_SIZE1<256 unsigned char rx_wr_index1,rx_rd_index1,rx_counter1; #else unsigned int rx_wr_index1,rx_rd_index1,rx_counter1; #endif // This flag is set on USART1 Receiver buffer overflow bit rx_buffer_overflow1; // USART1 Receiver interrupt service routine interrupt [USART1_RXC] void usart1_rx_isr(void) { char status,data; status=UCSR1A; data=UDR1; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) { rx_buffer1[rx_wr_index1]=data; if (++rx_wr_index1 == RX_BUFFER_SIZE1) rx_wr_index1=0; if (++rx_counter1 == RX_BUFFER_SIZE1) { rx_counter1=0; rx_buffer_overflow1=1; }; }; } // Get a character from the USART1 Receiver buffer #pragma used+ char getchar1(void) { char data; while (rx_counter1==0); data=rx_buffer1[rx_rd_index1]; if (++rx_rd_index1 == RX_BUFFER_SIZE1) rx_rd_index1=0; #asm("cli") --rx_counter1; #asm("sei") return data; } #pragma used- // USART1 Transmitter buffer #define TX_BUFFER_SIZE1 8 char tx_buffer1[TX_BUFFER_SIZE1]; #if TX_BUFFER_SIZE1<256 unsigned char tx_wr_index1,tx_rd_index1,tx_counter1; #else unsigned int tx_wr_index1,tx_rd_index1,tx_counter1; #endif // USART1 Transmitter interrupt service routine interrupt [USART1_TXC] void usart1_tx_isr(void) { if (tx_counter1) { --tx_counter1; UDR1=tx_buffer1[tx_rd_index1]; if (++tx_rd_index1 == TX_BUFFER_SIZE1) tx_rd_index1=0; }; } // Write a character to the USART1 Transmitter buffer #pragma used+ void putchar1(char c) { while (tx_counter1 == TX_BUFFER_SIZE1); #asm("cli") if (tx_counter1 || ((UCSR1A & DATA_REGISTER_EMPTY)==0)) { tx_buffer1[tx_wr_index1]=c; if (++tx_wr_index1 == TX_BUFFER_SIZE1) tx_wr_index1=0; ++tx_counter1; } else UDR1=c; #asm("sei") } #pragma used- // Standard Input/Output functions #include <stdio.h> // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port A initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00; DDRA=0x00; // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Port E initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTE=0x00; DDRE=0x00; // Port F initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTF=0x00; DDRF=0x00; // Port G initialization // Func4=In Func3=In Func2=In Func1=In Func0=In // State4=T State3=T State2=T State1=T State0=T PORTG=0x00; DDRG=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: Normal top=FFh // OC0 output: Disconnected ASSR=0x00; TCCR0=0x00; TCNT0=0x00; OCR0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // OC1C output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off // Compare C Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; OCR1CH=0x00; OCR1CL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // Timer/Counter 3 initialization // Clock source: System Clock // Clock value: Timer 3 Stopped // Mode: Normal top=FFFFh // Noise Canceler: Off // Input Capture on Falling Edge // OC3A output: Discon. // OC3B output: Discon. // OC3C output: Discon. // Timer 3 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off // Compare C Match Interrupt: Off TCCR3A=0x00; TCCR3B=0x00; TCNT3H=0x00; TCNT3L=0x00; ICR3H=0x00; ICR3L=0x00; OCR3AH=0x00; OCR3AL=0x00; OCR3BH=0x00; OCR3BL=0x00; OCR3CH=0x00; OCR3CL=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // INT2: Off // INT3: Off // INT4: Off // INT5: Off // INT6: Off // INT7: Off EICRA=0x00; EICRB=0x00; EIMSK=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; ETIMSK=0x00; // USART0 initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // USART0 Receiver: On // USART0 Transmitter: On // USART0 Mode: Asynchronous // USART0 Baud rate: 9600 UCSR0A=0x00; UCSR0B=0xD8; UCSR0C=0x06; UBRR0H=0x00; UBRR0L=0x5F; // USART1 initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // USART1 Receiver: On // USART1 Transmitter: On // USART1 Mode: Asynchronous // USART1 Baud rate: 9600 UCSR1A=0x00; UCSR1B=0xD8; UCSR1C=0x06; UBRR1H=0x00; UBRR1L=0x5F; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // Global enable interrupts #asm("sei") // Place your code here putchar1(0xa);putchar1(0xd);UART1_Write_Strf(" \n\r") UART1_Write_Strf("H - diese Hilfe \n\r"); while (1) { // Place your code here }; } MFG
HALLO; DANKE FÜR DIE ANTWORT, das ist für CodeWizardAVR den hab ich leider nicht habe nur das AVRStudio, bekomme das einfach nicht hin das der m128 nur nen text zum terminalprogramm schickt kommen nur kryptische zeichen an,hatte schon versucht das uart tutorial vom mega8 auf den m128 umzuschreiben aber das klappte nicht,vielleicht könnte mir von euch einer ein bischen weiterhelfen, das der m128 erstmal nur ein text zum terminal schickt das wäre fürn anfang super. danke mfg kay
> kommen nur kryptische zeichen an Ein sicheres Indiz dafür, dass die Baudrate nicht stimmt. Die häufigste Ursache dafür ist, daß der Prozessor immer noch auf internem Takt läuft und nicht auf Qaurzbetrieb. > habe soeben noch mal die FUSES nachgeschaut, > die Fuses Jtag und 103 modus sind deaktiviert, mega128 läuft mit > 14,745600MHz Quarz, Woran machst du fest, dass der Quarz auch aktiv ist? Der muss mit Fuses eingeschaltet werden, einfach nur den Quarz anschliessen ist zuwenig. Zum Programm: Für die ersten Tests würde ich mal einen ganz einfachen Test benutzen: In einer Schleife immer wieder dasselbe Zeichen schicken.
Halloöle kay Das ist nicht für den code Wizard sondern mit diesem erstellt. Du hattest nichts geschrieben, über deine Plattform. Auch wenn du Dich mit C nicht auskennen solltest kannst du die entscheidenden Initialisierungen entnehmen. Ich habe extra Deine Quarzfrequenz eingestellt, um die Baudrate richtig ausrechnen zu lassen. Wichtig ist bei den Fuses , das es sich um negative Logik handelt. Das heißt Bit programmiert = 0, Bit unprogrammiert = 1 CKSEL0 = 1 unprogrammiert CKSEL1 = 1 unprogrammiert CKSEL2 = 1 unprogrammiert CKSEL3 = 1 unprogrammiert SUT0 = 0 programmiert SUT1 = 1 unprogrammiert BODEN = 1 unprogrammiert BODLEVEL = 1 unprogrammiert BOOTRST = 1 unprogrammiert BOOTSZ0 = 1 unprogrammiert BOOTSZ1 = 1 unprogrammiert EESAVE = 1 unprogrammiert CKOPT = 1 unprogrammiert JTAGEN = 1 unprogrammiert OCDEN = 1 unprogrammiert WDTON = 1 unprogrammiert M103C = 1 unprogrammiert
hallo winne, die logik mit den fuse habe ich verstanden,sind auch richtig gesetzt, mit C kenn ich mich nicht aus. hallo Karl heinz Buchegger, habe jetzt mal versucht ein T zum pc zu schicken aber es kommt immer noch mist an, egal welche baudrate ich am pc terminal programm einstelle. habe schon überall nachgeschaut aber nirgends finde ich ein beispiel für den mega128 uart1 in asm, vielleicht könnte mir da einer behilflich sein dnake mfg kay
Nun ja. Wenn du das auszugebende Zeichen in das Register temp1 (=r19) lädst, aber in der Subroutine USART_Transmit gleich mal als erstes den Zustand von UCSR1A ebenfalls nach temp1 holst, dann wird da wohl das auszugebende Zeichen sofort überschrieben werden.
Nachtrag: Ein Unterprogramm aufzurufen ohne vorher den Stackpointer gesetzt zu haben, wird wahrscheinlich auch nicht so gut kommen.
genau das ist der Haken mit den temp varieablen verwirrst du dich nur selbst der 128er verfügt über hinreichend SRAM es ist nicht nötig mit registervariablen zu geizen, wie bei den Tinys einfach etwas großzügiger variablen definieren. und das gehädder hat ein Ende
so habs nochmal umgeändert aber haut immer noch nicht hin bin bald am verzweifeln mfg kay .include "m128def.inc" ;Namen für Ports .equ CLOCK = 14745600 .equ BAUD1 = 9600 .equ UBRRVAL = CLOCK/(BAUD1*16)-1 .def temp1 = R19 .def temp2 = R20 .def temp3 = R21 ldi temp1, LOW(RAMEND) out SPL, temp1 ldi temp1, HIGH(RAMEND) out SPH, temp1 ; Baudrate einstellen ldi temp1, LOW(UBRRVAL) sts UBRR1L, temp1 ldi temp1, HIGH(UBRRVAL) sts UBRR1H, temp1 ; RX1 / TX1 aktivieren ;ldi temp1, (1<<RXEN1)|(1<<TXEN1) ;TX1 aktivieren ldi temp1,(1<<TXEN1) sts UCSR1B,temp1 ; Set frame format: 8data, 2stop bit ldi temp1, (1<<USBS1)|(3<<UCSZ10) sts UCSR1C,temp1 loop: ldi temp1, 'T' rcall USART_Transmit ; Unterprogramm aufrufen rjmp loop USART_Transmit: ; Wait for empty transmit buffer ;push temp1 lds temp2, UCSR1A sbrs temp2 ,UDRE1 rjmp USART_Transmit ; Put data (r18) into buffer, sends the data ;pop temp1 sts UDR1,temp2 ;temp2 ret ;USART_Receive: ; Wait for data to be received ;push temp1 ;lds temp1, UCSR1A ;sbrs temp1 ,RXC1 ;rjmp USART_Receive ; Get and return received data from buffer ;pop temp1 ;lds temp3, UDR1 ;ret
wie ich sehe hast du dies versucht mit push & pop über den stack zuretten. dann musst du es aber auch in der richtigen reihenfolge tun. sonst kann es nichts werden.
hallo winne, ""dann musst du es aber auch in der richtigen reihenfolge tun"" so in etwa, USART_Transmit: ; Wait for empty transmit buffer push temp2 lds temp2, UCSR1A sbrs temp2 ,UDRE1 rjmp USART_Transmit ; Put data (r18) into buffer, sends the data pop temp2 sts UDR1,temp2 ret aber auch so funktionierts nicht, mfg kay
Kay B. wrote: > hallo winne, > ""dann musst > du es aber auch in der richtigen reihenfolge tun"" > > so in etwa, > > USART_Transmit: > ; Wait for empty transmit buffer > push temp2 > lds temp2, UCSR1A > sbrs temp2 ,UDRE1 > rjmp USART_Transmit > ; Put data (r18) into buffer, sends the data > pop temp2 > sts UDR1,temp2 > ret > > > aber auch so funktionierts nicht, Das kann nicht funktionieren. Damit müllst du dir den Stack zu, weil du in jedem Schleifendurchlauf in dem auf die Freigabe von der UART gewartet wird ein erneuter Push auf den Stack erfolgt. > > mfg kay
HALLO, HATTE DIE USART_Transmit SO AUS DEM DATENBLATT vom m128; wie schreibt mann es denn nun richtig , ich bekomme das einfach nicht hin. mfg kay
Kay B. wrote: > USART_Transmit: > ; Wait for empty transmit buffer > ;push temp1 > lds temp2, UCSR1A > sbrs temp2 ,UDRE1 > rjmp USART_Transmit > ; Put data (r18) into buffer, sends the data > ;pop temp1 > sts UDR1,temp2 ;temp2 > ret Wie wäre es, wenn du nicht einfach nur drauflos hackst, sondern mal ein bischen Sorgfalt walten lässt (und deinen Code etwas leserlicher formatierst, dann passieren dir auch nicht solch blödsinnige Fehler) Wo passiert die Ausgabe auf die UART? Hier > sts UDR1,temp2 ;temp2 Was gibst du aus? Den Inhalt von temp2 temp2 enthält aber nicht das auszugebende Zeichen. Dieses steht in temp1. Vorschlag: Benenne deine Register mal richtig nach dem Verwendungszweck. Dann fallen dir solche Dinge auch auf. (Ohne Gewähr, da ich den Rest nicht geprüft habe)
1 | .include "m128def.inc" ;Namen für Ports |
2 | |
3 | .equ CLOCK = 14745600 |
4 | .equ BAUD1 = 9600 |
5 | .equ UBRRVAL = CLOCK/(BAUD1*16)-1 |
6 | |
7 | .def temp1 = R19 ; Register zur kurfristigen allgemeinen Verwendung |
8 | .def zeichen = r20 ; Zeichenuebergabe an die USART Ausgabefunktion |
9 | |
10 | ldi temp1, LOW(RAMEND) |
11 | out SPL, temp1 |
12 | ldi temp1, HIGH(RAMEND) |
13 | out SPH, temp1 |
14 | |
15 | ; Baudrate einstellen |
16 | ldi temp1, LOW(UBRRVAL) |
17 | sts UBRR1L, temp1 |
18 | ldi temp1, HIGH(UBRRVAL) |
19 | sts UBRR1H, temp1 |
20 | |
21 | ; TX1 aktivieren |
22 | ldi temp1, (1<<TXEN1) |
23 | sts UCSR1B, temp1 |
24 | |
25 | ; Set frame format: 8data, 2stop bit |
26 | ldi temp1, (1<<USBS1)|(3<<UCSZ10) |
27 | sts UCSR1C, temp1 |
28 | |
29 | loop: |
30 | ldi zeichen, 'T' |
31 | rcall USART_Transmit |
32 | |
33 | rjmp loop |
34 | |
35 | USART_Transmit: |
36 | ; Wait for empty transmit buffer |
37 | lds temp1, UCSR1A |
38 | sbrs temp1, UDRE1 |
39 | rjmp USART_Transmit |
40 | |
41 | sts UDR1, zeichen |
42 | ret |
hallo Karl heinz Buchegger, SO NUN GEHTS AUCH MIT NEN STRING, DANKE NOCHMALS FÜR DIE MÜHE .include "m128def.inc" ;Namen für Ports .equ CLOCK = 14745600 .equ BAUD1 = 9600 .equ UBRRVAL = CLOCK/(BAUD1*16)-1 .def temp1 = R19 .def zeichen = r20 ldi temp1, LOW(RAMEND) out SPL, temp1 ldi temp1, HIGH(RAMEND) out SPH, temp1 ; Baudrate einstellen ldi temp1, LOW(UBRRVAL) sts UBRR1L, temp1 ldi temp1, HIGH(UBRRVAL) sts UBRR1H, temp1 ; TX1 aktivieren ldi temp1, (1<<TXEN1) sts UCSR1B, temp1 ; Set frame format: 8data, 2stop bit ldi temp1, (1<<USBS1)|(3<<UCSZ10) sts UCSR1C, temp1 loop: ldi ZL, LOW(text*2) ; Adresse des Strings in den ldi ZH, HIGH(text*2) ; Z-Pointer laden rcall print ; Unterfunktion print aufrufen ;ZEILENUMBRUCH ldi zeichen, 10 rcall USART_Transmit ldi zeichen, 13 rcall USART_Transmit ldi ZL, LOW(text1*2) ; Adresse des Strings in den ldi ZH, HIGH(text1*2) ; Z-Pointer laden rcall print ; Unterfunktion print aufrufen ;ZEILENUMBRUCH ldi zeichen, 10 rcall USART_Transmit ldi zeichen, 13 rcall USART_Transmit ldi ZL, LOW(text2*2) ; Adresse des Strings in den ldi ZH, HIGH(text2*2) ; Z-Pointer laden rcall print ; Unterfunktion print aufrufen ;ZEILENUMBRUCH ldi zeichen, 10 rcall USART_Transmit ldi zeichen, 13 rcall USART_Transmit ldi ZL, LOW(text3*2) ; Adresse des Strings in den ldi ZH, HIGH(text3*2) ; Z-Pointer laden rcall print ; Unterfunktion print aufrufen ;ZEILENUMBRUCH ldi zeichen, 10 rcall USART_Transmit ldi zeichen, 13 rcall USART_Transmit rjmp loop ; print: sendet die durch den Z-Pointer adressierte Zeichenkette print: lpm ; Erstes Byte des Strings nach R0 lesen tst R0 ; R0 auf 0 testen breq print_end ; wenn 0, dann zu print_end mov zeichen, r0 ; Inhalt von R0 nach R16 kopieren rcall USART_Transmit ; UART-Sendefunktion aufrufen adiw ZL, 1 ; Adresse des Z-Pointers um 1 erhöhen rjmp print ; wieder zum Anfang springen print_end: ret USART_Transmit: ; Wait for empty transmit buffer lds temp1, UCSR1A sbrs temp1, UDRE1 rjmp USART_Transmit sts UDR1, zeichen ret text: .db "AVR-Assembler ist ganz einfach",0 ; Stringkonstante, durch eine 0 abgeschlossen text1: .db "NICHT IMMER",0 ; Stringkonstante, durch eine 0 abgeschlossen text2: .db "12345678910",0 ; Stringkonstante, durch eine 0 abgeschlossen text3: .db "ATMEGA128",0 ; Stringkonstante, durch eine 0 abgeschlossen DANKE MFG KAY
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.