Problem mit Interupts

OP #2060299
Lesenswert?

Hallo,
ich möchte einen Interrupt auf einem Attini13 in C programmieren. Die 
Forensuche und Google haben mir als Anfänger nicht wirklich geholfen. 
Wäre es möglich das mir jemand einmal erklären kann, was ich da an Code 
brauche um den Interupt erstmal zu programieren und dann wie ich da ein 
Ereignis daran koppel kann? Da ich noch ein ziemlicher Anfäger bin würde 
ich mich über eine leicht verständliche Erklärung freuen.

Gruß Jannis
OP #2060320
Lesenswert?

Erstmal Danke, für die schnelle Antwort. Wie ich jedoch schon gesagt 
habe ich mir auch diesen Artikel bereits durchgelesen, werde daraus aber 
nicht schlau. Dazu muss gesagt werde, dass ich
1)Noch Schüler bin
2)Erst 15 bin
3)Und ich mit einigen Begriffen aus dem Artikel nichts Anfangen kann.
Meine aktuelle Frage bezieht sich nur auf ein paar Befehle die ich gerne 
wissen möchte weil ich sie nicht selber finde.
Gruß Jannis
#2060325
Lesenswert?

@  Jannis C. (kabelwurm)

>Erstmal Danke, für die schnelle Antwort. Wie ich jedoch schon gesagt
>habe ich mir auch diesen Artikel bereits durchgelesen,

Das hast du WO geschrieben . . .?

> werde daraus aber nicht schlau.

Schade.

> Dazu muss gesagt werde, dass ich
>1)Noch Schüler bin
>2)Erst 15 bin

Waren wir alle mal.

>3)Und ich mit einigen Begriffen aus dem Artikel nichts Anfangen kann.

Welchen?

>Meine aktuelle Frage bezieht sich nur auf ein paar Befehle die ich gerne
>wissen möchte weil ich sie nicht selber finde.

Lies mal was über Netiquette und stelle konkrete Fragen.

MfG
Falk
OP #2060393
Lesenswert?

Hallo,
um deine Fragen eine nach der anderen zu beantworten:
In meine ersten Beitrag habe ich geschrieben, dass ich nach Netiquette 
erst die Forensuche benutzt habe. Dabei bin ich auch auf den 
Interuptartikel gestoßen und habe diesen auch studiert.
Die Wiki ist eine tolle Sache die ich auch nicht kritisieren möchte. 
Meiner Ansicht nach verlangt sie jedoch gewisse Grundtkentnisse, die ich 
leider noch nicht habe. Lernen möchte ich das jedoch.
Warum ich das mit meinem Alter und so geschrieben habe: Weil ich damit 
zeigen wollte das ich eben nicht über Kompetenzen verfüge, die mir beim 
Verstehen des Artikles helfen würden.
Bei den Begriffen geht es um dieverse Register und den Zusammenhang 
zwischen ihnen. Das wird sich sicher mit der Zeit von alleine klären, 
wenn ich damit zu tun habe.
ich kann dir mein Proket schildern:
Eine Taste wird gedrückt, daruf hin soll eine Aktion folgen.
Ich habe in der Wiki explizit danach gesucht, es kann auch sein das es 
dadrin steht, ich es aber nicht erkenne.
Ich hoffe ich werde hiermit deiner Frage nach konkreten Infortionen 
gerecht. Über Antworten freue ich mich weiterhin.
Gruß Jannis
Gast #2060414
Lesenswert?

Dann stell doch bitte eine Kronkrete Frage. In den wiki artikel sind 
ausreichend beispiele für programme mit Interupt.

Wenn du auf einen Taster reagieren willst dann willst du es vermutlich 
über den PIN-Change interrupt machen, also sucht du aus der doku den 
namen für den interupt und schreibst eine funktion nach der anleitung im 
Wiki.

(Zum üben ist es ok, aber ein großteil der leute werden dir eh empfehlen 
die tasten nicht im Interupt auszuwerten weil es probleme machen kann)
Gast #2060429
Lesenswert?

> Meiner Ansicht nach verlangt sie jedoch gewisse Grundtkentnisse, die ich
> leider noch nicht habe.

Bester Quell für Informationen wie der Tschipp überhaupt funktioniert: 
dessen Datenplatt [1]. Lies Dir das mal (vorzugsweise vollständig!) 
durch, dann wirst Du auch sehen dass..

> Bei den Begriffen geht es um dieverse Register und den Zusammenhang
> zwischen ihnen.

..ebendiese Register (und was sie tun) nicht vom Himmel gefallen sind - 
alles fein säuberlich dokumentiert. Wenn Du mit dem Datenplatt durch 
bist wirst Du auch sehen (wissen :-) dass es per Design mehrere 
Möglichkeiten gibt, um..

> Eine Taste wird gedrückt, daruf hin soll eine Aktion folgen.

..zu lösen. (Namentlich, ohne Anspruch auf Vollständigkeit: Interrupt 
INT0, Interrupts PCINT0-5, Pin-Abfrage PINx - was die Unterschiede sind 
und warum nicht jede (technisch mögliche) Lösung zu jedem Problem passt 
steht u.a. im Datenplatt).

So, ich hoffe ich konnte helfen. Viel Spaß beim lesen, ich freue mich 
schon auf ∗konkrete∗ Fragen :-)

HTH

[1] http://atmel.com/dyn/resources/prod_documents/doc2535.pdf
Gast #2060684
Lesenswert?

> ich wusste nicht, das es noch andere Lösungen gibt. Welche wären das
> denn?

Bitte bitte tu Dir selbst einen Gefallen und lies endlich das 
Datenplatt. Jetzt. Vollständig.

Und im Anschluss das bereits genannte avr-gcc-Tutorial. Ebenfalls 
vollständig. Vorne beginnend.

Glaubs mir, alle Deine (bisherigen) Fragen werden in den genannten 
Dokumenten ausführlich beantwortet. Und wenn Du durch beide durch bist, 
dann hast Du auch genug Grundlagenkenntnisse, auf die man aufbauen kann.

HTH und - nix für ungut - EOD
OP #2060824
Lesenswert?

Ich habe mal im Toturial und im Datenblatt gestöbert und daraufhin 
folgenden Code geschrieben. Der macht beim Simulieren aber nicht das was 
ich will. Der Stil ist wahrscheinlich noch suboptimal. Der Großeil ist 
aus dem Toturial kopiert. Compilieren kann ich es auch ohne Warnungen 
oder Fehler. Letztenendlich soll das ein Test werden. Der Taster wird 
gedrückt (PORTB4) und daraufhin schalten sich PORTB0-3 nacheinander an.
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6

7
int main (void) 
8
 {
9
 DDRB = 0b00001111;
10
 if ( PINB & (1<<PINB4) ) 
11
 {
12
 PORTB =0b00000001;
13
 _delay_ms(1000);
14
 PORTB =0b00000011;
15
 _delay_ms(1000);
16
 PORTB =0b00000111;
17
 _delay_ms(1000);
18
 PORTB =0b00001111;
19
 _delay_ms(1000);
20
  
21
 PORTB =0b00000000;
22

23
   }
24
    
25
}
Gruß Jannis
OP #2060891
Lesenswert?

Danke für den Tip,
habe den auch gleich umgesetzt:
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6

7
int main (void) 
8
 {
9
 DDRB = 0b00001111;
10
 while (1){
11
 if ( PINB &(1<<PINB4) ) 
12
 {
13
 PORTB =0b00000001;
14
 _delay_ms(1000);
15
 PORTB =0b00000011;
16
 _delay_ms(1000);
17
 PORTB =0b00000111;
18
 _delay_ms(1000);
19
 PORTB =0b00001111;
20
 _delay_ms(1000);
21
  
22
 PORTB =0b00000000;
23
 }
24

25
 }
26
   return(0);
27
}
im Simulator zeigt er aber die Angeschalteten Ausgänge nicht an. Ist das 
irgendwie relevant?
Gruß Jannis
OP #2062831
Lesenswert?

Hallo,
das Programm um das es geht funktioniert nicht so wirklich so wie ich 
das will. Wenn ich den Chip in die Platiene setze und 5V anlege, 
schalten sich die Ports0-3 einfach so an, ohne das PORTB4 ein Signal 
erhalten hat. Es liegt weder Spannung an, noch sind irgendwelche 
Verbindungen vorhanden.
Mein Quelltext:
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6

7
int main (void) 
8
 {
9
 DDRB = 0b00001111;
10
 while (1){
11
 if ( PINB &(1<<PINB4) ) 
12
 {
13
 PORTB =0b00000001;
14
 _delay_ms(1000);
15
 PORTB =0b00000011;
16
 _delay_ms(1000);
17
 PORTB =0b00000111;
18
 _delay_ms(1000);
19
 PORTB =0b00001111;
20
 _delay_ms(1000);
21
 PORTB =0b00000000;
22
 _delay_ms(1000);
23
 
24
 }
25

26
 }
27
   return(0);
28
    
29
}
Was feht oder ist ligisch falsch?
Gruß Jannis
Gast #2062838
Lesenswert?

Jannis C. schrieb:
> Wenn ich den Chip in die Platiene setze und 5V anlege,
> schalten sich die Ports0-3 einfach so an, ohne das PORTB4 ein Signal
> erhalten hat.

Wie ist dein Taster verschaltet? Der Eingang ist hochohmig, daher ist 
der Zustand des Pin4 ohne definierte Pegel (Pullup oder Pulldown) 
abhängig davon, ob Radio 7 grade Musik spielt oder nicht.
:-)
OP #2062849
Lesenswert?

Ich habe in ersmal garnicht verschaltet und nur eine Prüfspitze an die 
Versorgunsspannung gehängt. Ich bin auch nicht festgelegt auf die 
Abfrage des Pins. Wenn es eine bessere und praktikanlere Lösung gibt 
freu ich mich darüber. In der dafür geplanten Schaltung sind auch nur 
dierekt Schalter angeschlossen
Gruß Jannis
#2062863
Lesenswert?

Jannis C. schrieb:
> Ich habe in ersmal garnicht verschaltet und nur eine Prüfspitze an die
> Versorgunsspannung gehängt.

Mit anderen Worten:
Die Eingänge sind offen und können sich jedes dahergelaufene 
elektromagnetische Feld wahlweise als 0 oder als 1 einfangen.

> Ich bin auch nicht festgelegt auf die
> Abfrage des Pins. Wenn es eine bessere und praktikanlere Lösung gibt
> freu ich mich darüber.

Pullup Widerstände einschalten
AVR-GCC-Tutorial
AVR-Tutorial

denn das ...
> schalten sich die Ports0-3 einfach so an, ohne das PORTB4
> ein Signal erhalten hat. Es liegt weder Spannung an
... ist ein Trugschluss.

Ein Eingang, an dem nichts angeschlossen ist, ist nicht zwangsläufig auf 
0.
OP #2062872
Lesenswert?

Hallo,
erstmal Danke für die scnelle Antwort.
Ich habe deinen Tip gleich angewendet. Dank des Tutorials ist das 
problemlos möglich. Nach der korrektur sieht der Code dann so aus:
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6

7
int main (void) 
8
 {
9
 DDRB = 0b00001111;
10
 PORTB |= (1<<PB4);
11
 while (1){
12
 if ( PINB &(1<<PINB4) ) 
13
 {
14
 PORTB =0b00000001;
15
 _delay_ms(1000);
16
 PORTB =0b00000011;
17
 _delay_ms(1000);
18
 PORTB =0b00000111;
19
 _delay_ms(1000);
20
 PORTB =0b00001111;
21
 _delay_ms(1000);
22
 PORTB =0b00000000;
23
 _delay_ms(1000);
24
 
25
 }
26

27
 }
28
   return(0);
29
    
30
}
Gruß Jannis
#2062879
Lesenswert?

Jannis C. schrieb:

> problemlos möglich. Nach der korrektur sieht der Code dann so aus:
> #include <avr/io.h>
> #ifndef F_CPU
> #define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
> #endif
> #include <util/delay.h>
>
> int main (void)
>  {
>  DDRB = 0b00001111;
>  PORTB |= (1<<PB4);
>  while (1){
>  if ( PINB &(1<<PINB4) )

Nur musst du jetzt noch berücksichtigen, dass durch den zugeschalteten 
Pullup Widerstand der 'Ruhepegel' des Eingangs eine 1 ist.

UND: Du musst natürlich darauf achten, dass du dir bei weitren 
Zuweisungen an den PORTB den Pullup Widerstand nicht wieder ausschaltest 
:-)

Hier zb
     PORTB =0b00000001;
setzt du Bit 4 vom Port B wieder auf 0. Und damit ist danach der Pullup 
Widerstand wieder weg.

Und bitte: rück deinen Code entsprechend ein, damit man sieht, welche 
Code-Blöcke von welchen { } Klammern umschlossen sind und somit logisch 
zusammengehören. Wenn deine Programme komplizierter werden, ist eine 
derartige Einrückung ein unabdingabres Werkzeug um nicht den Überblick 
zu verlieren.
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6

7
int main (void) 
8
{
9
  DDRB = 0b00001111;
10
  PORTB |= (1<<PB4);
11

12
  while (1) {
13
    if ( !(PINB &(1<<PINB4)) ) {
14
      PORTB =0b00000001;
15
      _delay_ms(1000);
16
      PORTB =0b00000011;
17
      _delay_ms(1000);
18
      PORTB =0b00000111;
19
      _delay_ms(1000);
20
      PORTB =0b00001111;
21
      _delay_ms(1000);
22
      PORTB =0b00000000;
23
      _delay_ms(1000);
24
    }
25
  }
26

27
  return 0;
28
}
#2062949
Lesenswert?

Jannis C. schrieb:
> Okay und was heißt das für mein Programm?

Das du es ändern musst?

Wenn bei dir Bit 4 am Port B immer 1 sein muss, dann wirst du wohl das 
hier
1
        PORTB =0b00000001;
so nicht machen können.

Allerdings würde
1
        PORTB =0b00010001;
das Bit 4 auf 1 lassen :-)

genauso wie
1
        PORTB = 0b00000001 | ( 1 << PB4 );

oder aber, wie zb
1
        PORTB |= (1<<PB0);
nur das Bit 0 im Port B setzt und alle anderen Bits in Ruhe lässt.

Viele Wege führen nach Rom.
#2063056
Lesenswert?

Jannis C. schrieb:
> Wäre es eine Lösung, wenn ich meine Bedingung ändere und sage, dass das
> Ereignis eintreten soll wenn PORTB4 nicht 1 ist ?

Nein. Das würde gar nichts ändern.
Denn das du den Pullup brauchst, darüber sind wir uns ja einig.

> Dann müsste es doch funktionieren, wenn ich am Ende der Schleife PORTB4
> wieder setze?

Das würde funktionieren.
Lerne aber trotzdem wie man es richtig macht und greif nicht zu solchen 
Hacks zurück.
Du baust ja auch in ein Zimmer einen Lichtschalter ein und zerstörst 
nicht abends die Glühbirne um dann am nächsten Tag eine neue 
einzuschrauben. Auch wenn das im Prinzip funktionieren würde.


Bits unabhängig von anderen Bits setzen und löschen zu können ist eine 
der Grundfertigkeiten in der µC Programmierung.
OP #2063741
Lesenswert?

Oh Sorry, das hatte ich vergessen.
Also ich möchte einfach einen Taster anschließen. Einen Schließer, der 
nur einen kurzen Kontakt ausgibt. Die weitere Verschaltung kann sowohls 
als Aktiv High, als auch Aktiv Low erfolgen. Da bin ich nicht 
festgelegt, da die Schaltung erst auf dem Papier existiert. Ich weiß 
leider nicht wie ich das Programmieren muss wenn ich eins davon 
verwende.
Gruß Jannis
#2064819
Lesenswert?

Jungs, das war kontraproduktiv.
Jetzt umgeht er sein Problem des 'Wie schaffe ich es, dass ich an einem 
Port nur die Bits ändere, die ich auch ändern will' mit einem externen 
Widerstand.

Dabei war er schon so dicht drann, dass er nachgefragt hätte, was 
eigentlich ganz genau

   PORTB |= (1<<P4);

macht und warum das jetzt für sein Problem hilfereich sein könnte, wenn 
er das begriffen hat.
Gast #2065722
Lesenswert?

Zusammenfassung bisher: Du hast einen Pin als EINGANG konfiguriert 
(DDRB) und fragst dessen Zustand ab (PINB). Am Pin soll ein Taster 
hängen.

Welchen Logikpegel kannst du bei obigen Voraussetzungen durch die 
PORTB-Anweisung sicher einstellen und so als definierten Ruhepegel 
(Taster nicht gedückt) benutzen? Tipp: Datenblatt.

Und welchen gegensätzlichen Logikpegel muss dein Taster dann beim 
Drücken liefern?

Zu welcher Schaltungsvariante in 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Tasten_und_Schalter 
passen diese Pegel?

Braucht man dann den externen Widerstand, wenn die PORTB-Anweisung 
verwendet wird?

Wie sieht die if-Bedingung für die neue Schaltung aus?
Gast #2071254
Lesenswert?

Jannis C. schrieb:
>>Kontrollieren, welches Bit da abgefragt wird.
> Ich würde sagen, das nach Tutorila mit PINx der Zustand des Pins
> abgefragt wird, und nicht der Pull up.

Das stimmt. Aber bist du dir sicher, daß es auch um den Pin handelt, den 
du abfragen willst?  (Tip:  Es ist nicht Pin B4)
Gast #2071263
Lesenswert?

> Ich würde sagen, das nach Tutorila mit PINx der Zustand des Pins
> abgefragt wird, und nicht der Pull up.

Ja, aber welches Bit?

Bei
#define PINB4 4

kann
PINB & PINB4 = 0000 1000
oder
PINB & PINB4 = 0000 0000
sein

Willst du das oder eher
PINB & XXXXX = 0001 0000
oder
PINB & XXXXX = 0000 0000

Wie kann XXXXX aus PINB4 gebildet werden? Tipp: Bitmanipulation
Gast #2073060
Lesenswert?

> ich gehöre leider zu der Fraktion, die kein Latein hat.

Ich auch. Jannis, vor dir ist ein beleuchtetes rechteckiges Fenster zum 
Wissen einer ganzen Welt. Benutz das!

> Ich verstehe nicht ganz, worauf du hinaus willst. Also, was ist die
> Lösung?

Du hast noch Probleme beim Verständnis des Unterschieds zwischen

if (!(PINB&(PINB4))
und
if (!(PINB&(1<<PINB4))

Die beiden Schreibweisen haben nicht die gleiche Funktion.

Du willst Bit PINB4 (= Bit4) in PINB abfragen, weil das der Pin ist, an 
dem der Taster hängen soll (vgl. Pinout-Skizze im Datenblatt).

Aber die erste Schreibweise fragt das Bit3 ab. Wenn du dich fragst, 
"Wieso?", knobele das aus z.B. mit Hilfe des Artikels 
Bitmanipulation und den Bitoperatoren & und <<.

Um bei der AVR-Programmierung weiter zu kommen, musst du den Unterschied 
aus dem Effeff kennen und anwenden können.
#2074823
Lesenswert?

Immer noch falsch.

PINB4  ist einfach nur eine (benannte) Zahl. Die 4 im Namen weißt darauf 
hin, dass es sich um die Zahl 4 handelt.

Die Zahl 4 hat das Bitmuster 00000100
(1<<PINB4) ist aber eine 1 um 4 Stellen nach links geschoben.
Das ergibt daher das Bitmuster  00001000

Noch auffälliger wird es, wenn man nicht eine Pinnummer nimmt, die 
selber eine 2-er Potenz ist.

PINB3  zb hat das Bitmuster  00000011   (für die Zahl 3)
1<<PINB3    ist aber         00000100   (eine 1 um 3 Stellen geschoben)


   PINB0  <=> 0      00000000
   PINB1  <=> 1      00000001
   PINB2  <=> 2      00000010
   PINB3  <=> 3      00000011
   PINB4  <=> 4      00000100
   PINB5  <=> 5      00000101
   PINB6  <=> 6      00000110
   PINB7  <=> 7      00000111


das ist aber ganz was anderes als

  1 << PINB0         00000001
  1 << PINB1         00000010
  1 << PINB2         00000100
  1 << PINB3         00001000
  1 << PINB4         00010000
  1 << PINB5         00100000
  1 << PINB6         01000000
  1 << PINB7         10000000

'zufällig' ist jetzt aber die Bitrepräsentierung von PINB4 identisch zu 
1<<PINB2. Das ist aber nur bei diesem Pärchen so, bei anderen Nummern 
versagt das völlig.
#2074865
Lesenswert?

Jannis C. schrieb:
> Hallo,
> Sorry, da hab ich mich verschrieben.
> ich meinte die Binärzuweisung
> 0b00000011.
> Würde das auch gehen?

Klar.

Was dir noch fehlt.

Im Computer gibt es keine Unterscheidung zwischen dezimal, binär oder 
hexadezimal. Es ist alles dasselbe. Entweder eine Speicherzelle (=Bit) 
ist im aktiven Zustand oder im inaktiven Zustand. Ob wir das als 0 oder 
1, oder als * und o oder in Form einer Dezimalzahl oder .... darstellen, 
ist eine reine Frage der Anzeige.

0b0000011   IST die Zahl 3, genauso wie es 3 oder 0x03 wäre. Das sind 
alles nur verschiedene Schreibweisen desselben Sachverhaltes.

Manchmal ist die Binäre Schreibweise dem Problem besser angepasst, 
manchmal sind es Dezimalzahlen.

Wenn ich die Binärzahl 00000001  um 5 Stellen nach links schieben will, 
dann ist die dazu angebrachte Schreibweise nun mal

    0b00000001 << 5

denn da kann ich unmittelbar sehen, dass um 5 Stellen geschoben wird. 
Was ich bei

   0b00000001 << 0b00000101

nicht unmittelbar sehen würde (ausser ich kann gut Binärzahlen lesen, 
was die meisten Programmierer können).

Aber grundsätzlich sind beide Fassungen eins. Es besteht kein 
Unterschied zwischen ihnen. Sie sind nur andere Schreibweisen. Genauso 
wie

   1 << 5

auch nur eine andere Schreibweise ist.

Und genauso wie ich anstelle von 2 + 3 auch einfach 5 schreiben könnte, 
könnte ich natürlich auch vorgreifen, und selbst die Schiebeoperation 
durchführen und statt dessen einfach

   0b00100000

schreiben. Nur möchte man das nicht tun, denn im letzten Fall muss ich 
Bits abzählen um zu erkennen, an welcher Bitposition die 1 steht, 
während bei

   1 << 5

unmittelbar an der Schreibweise ablesbar ist, dass die 1 an der 
Bitposition 5 steht.

Und wenn ich dann noch in C vereinbare

#define LED_PIN   5

und schreibe

   PORTB |= (1<<LED_PIN);

dann brauch ich beim Lesen des Codes auch nicht mehr verinnerlichen, 
dass es sich beim Pin 5 um den Anchluss handelt an dem die LED hängt. 
Ich muss nur noch erkennen dass mittels

   x |= (1<<irgendwas);

ein Bit auf 1 gesetzt wird, im obigen Beispiel also der AUsgang an dem 
die LED hängt.
Bei
   PORTB |= ( 1 << LED_PIN );
interessiert mich daher gar nicht mehr, um welchen Pin es konkret geht. 
Das wichtige an dieser Stelle besteht darin, dass hier der Ausgang an 
dem die LED angeschlossen ist auf 1 gesetzt wird. Damit ist aber die 
ganze Anweisung aus dem Bereich von Binärzahlen in meinen Problembereich 
gehievt worden. Ich ärgere mich nicht mehr mit irgendwelchen Zahlen rum, 
sondern bei diesem Statement denke ich in Einheiten wie "LED 
einschalten" "LED ausschalten" etc.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren