Unterschiedliche Programme mit einem Schalter "wählen" (PIC 16F630)

Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte

Elektronik Forum Nicht eingeloggt       Einloggen       Registrieren




[Registrieren]      --     [FAQ]      --     [ Einen Link auf Ihrer Homepage zum Forum]      --     [ Themen kostenlos per RSS in ihre Homepage einbauen]      --     [Einloggen]

Suchen


Serverzeit: 02 1 2025  23:00:26      TV   VCR Aufnahme   TFT   CRT-Monitor   Netzteile   LED-FAQ   Osziloskop-Schirmbilder            


Elektronik- und Elektroforum Forum Index   >>   Microcontroller        Microcontroller : Hardware - Software - Ideen - Projekte

Gehe zu Seite ( 1 | 2 Nächste Seite )      


Autor
Unterschiedliche Programme mit einem Schalter "wählen" (PIC 16F630)
Suche nach: schalter (25810) pic (2056)

    







BID = 373802

Peo

Gesprächig



Beiträge: 181
Wohnort: Baden-W.
 

  


Hallo

Ich würde gerne auf meinem PIC 16F630 mehrere Programme laufen haben, die ich mit Hilfe eines Tasters nacheinander aufrufen möchte.

Dazu müsste ich doch PORTA, bit 3, lediglich als Input konfigurieren und dann mit btfss/btfsc PORTA,3 abfragen können, ob dort der Schalter geschlossen ist oder nicht.
Der Rest von PortA müsste doch als Output weiterhin zur Verfügung stehen?

Sehe ich das richtig?

mfg

Peo

BID = 373830

Ltof

Inventar



Beiträge: 9347
Wohnort: Hommingberg

 

  


Zitat :
Peo hat am 30 Sep 2006 16:13 geschrieben :

die ich mit Hilfe eines Tasters nacheinander aufrufen möchte...
...ob dort der Schalter geschlossen ist oder nicht.

Schalter oder Taster?

RA3 ist immer Input, egal wie der Port sonst konfiguriert ist. Wenn der für eine solche Funktion verwendet wird, hat der PIC natürlich keinen externen Reset mehr.

Dem Controller ist es egal , ob er in Abhängigkeit eines Portpins verschiedene "Hauptprogramme" oder Unterprogramme abarbeitet. Weder programmiertechnisch noch sonstwie macht das einen Unterschied.

Ein Schalter für zwei Programme ist natürlich einfacher zu programmieren. Den Portpin fragt das Programm ab und zu ab und entscheidet dann, ob es in dem Programm bleibt oder in das andere springt.

Sollen es mehr als zwei Programme sein und ein Taster zum Einsatz kommen, geht das beispielsweise mit einem Interrupt. Das macht dann Sinn, wenn das Programm recht lange läuft, es aber sofort auf die Taste reagieren soll. Wenn das Programm eine recht kurze Durchlaufzeit hat, reicht es, den Port zyklisch abzufragen.

Der Taster muss entprellt werden. Nach Bemerken des Tastendrucks muss einige Millisekunden gewartet werden. Danach kann noch eine Abfrage rein, ob der Taster wieder losgelassen wurde.

Gruß,
Ltof

_________________
„Schreibe nichts der Böswilligkeit zu, was durch Dummheit hinreichend erklärbar ist.“
(Hanlon’s Razor)

[ Diese Nachricht wurde geändert von: Ltof am 30 Sep 2006 18:09 ]

BID = 373946

Peo

Gesprächig



Beiträge: 181
Wohnort: Baden-W.

Danke für die schnelle Antwort und entschuldige bitte meine unpräzise Ausdrucksweise.
Es ging mir um den Taster.

Die Frage, die mich jetzt hier hauptsächlich bewegt ist, wie ich den Interrupt machen kann, da das geplante Programm (eine Ampelsteuerung) ziemlich lange läuft (ca. 40 Sekunden).

Nunmehr habe ich das Problem, dass ich mit den Datenblättern nicht weiter komme, da ich, zugegebener Maßen, zu wenig Ahnung von Pcs habe.

Wie mache ich das mit dem Interrupt?
Wenn man mir damit helfen könnte, wäre das wunderbar.

mpg

Peo

BID = 373996

Ltof

Inventar



Beiträge: 9347
Wohnort: Hommingberg

Moin Peo,

zunächst mal eine Ergänzung meiner obigen Behauptung bezüglich mehrerer "Hauptprogramme" im Pic:
Gleichnamige Sprungmarken dürfen nicht mehrmals auftauchen. Variablen, die in allen Programmen verwendet werden, verändern natürlich den Wert. Variable X hat beim erneuten Sprung in "Programm 1" natürlich nicht mehr den ursprünglichen Wert, wenn diese in "Programm 2" auch verwendet wurde.

Sind Deine Hauptprogramme alleine bereits lauffähig gewesen, so sind zum zusammen Benutzen gegebenenfalls Variablennamen und Sprungmarken anzupassen.

Interrupts kann ich auch nicht besser erklären als Sprut:
http://www.sprut.de/electronic/pic/int/int.htm

Wenn irgend möglich, würde ich auf Interrupts verzichten (und Andere, die etwas davon verstehen, empfehlen das auch).

Für Deine Anwendung fällt mir noch eine dritte Möglichkeit ein:
Statt die Taste direkt abzufragen und darauf zu reagieren, wird an geeigneter Stelle (z.B. in den Warteschleifen der Ampelsteuerung) auf Tastendruck eine Flagge ("flag") gesetzt. Diese Flagge ist einfach ein Bit einer selbst deklarierten Variable. Der Tastendruck wird also gespeichert und an den richtigen Stellen wird darauf reagiert. Die Information des Tastendruckes geht also nicht verloren, selbst wenn die Taste längst wieder losgelasen wurde. Die Flagge wird dann nach Abarbeiten der Reaktion zurückgesetzt.

Gruß,
Ltof

_________________
„Schreibe nichts der Böswilligkeit zu, was durch Dummheit hinreichend erklärbar ist.“
(Hanlon’s Razor)

[ Diese Nachricht wurde geändert von: Ltof am  1 Okt 2006  8:56 ]

BID = 374105

Peo

Gesprächig



Beiträge: 181
Wohnort: Baden-W.

Du meinst also, dass ich z. B. die Variable TASTER habe, die in der Initialisierung den Wert '00000000' erhält, und folgenden Code eingebe:

btfsc TRISA,3 ;RA3 wird hier abgefragt
movlw .1
btfsc TRISA,3
movwf TASTER

Dann könnte ich in einem späteren Programmabschnitt abfragen, ob der Taster gedrückt wurde, da ja die Variable TASTER nun den Wert 1 hat?

Wenn dem so ist, wie Frage ich den Wert der Variable ab?


mfg

Peo


BID = 374159

Ltof

Inventar



Beiträge: 9347
Wohnort: Hommingberg

So umständlich muss es nicht sein und außerdem enthält es einen gravierenden Fehler:
Nicht TRISA,3 wird abgefragt, sondern PORTA,3

Also etwa so:
btfsc porta,3
bsf Tastendruck

"Tastendruck" ist ein Bit, welches so deklariert wird:

Flags equ 0x25 (oder eine andere freie Ram-Adresse)
#define Tastendruck Flags,0

Nun ist Bit0 des Bytes "Flags" das Bit für das Speichern des Tastendrucks.

Das kannst Du genauso mit btfs* abfragen wie ein Portbit.
Du musst es dann nur an passender Stelle wieder selbst löschen, sonst denkt der µC ständig, er müsse auf den Tastendruck reagieren.

Eine Frage:
Hast Du bereits ein selbst geschriebenes, lauffähiges Programm? Z.B. die Ampelsteuerung?

Gruß,
Ltof

_________________
„Schreibe nichts der Böswilligkeit zu, was durch Dummheit hinreichend erklärbar ist.“
(Hanlon’s Razor)

BID = 374170

Peo

Gesprächig



Beiträge: 181
Wohnort: Baden-W.

Hallo

Wenn ich also das Flag setze, frage ich vor dem Springen nur, ob das Flag besetzt ist oder nicht. z.B.
btfss Tastendruck
goto Programm1
btfsc Tastendruck
goto Programm2


kann ich das Flagbit auch mit
decfsz Tastendruck
nop

jeweils zwischen 0 und 1 wechseln?

Das Programm unten ist etwas verschachtelt.
Die Ampelsteuerung ist zu Versuchszwecken mit schnellem Blinken ersetzt worden.

Das Programm startet im AMPEL und wenn der Taster gedrückt wird, also RA3 Spannung erhält, dann wird im delayloop1 auf wechselzuloop2 verwiesen. Dort bleibt der µC, bis der Taster losgelassen wird (Abfrage jede Millisekunde), dann springt der µC in Loop2 - das zweite Hauptprogramm.
Wenn der Taster wieder gedrückt wird, geschieht in delayloop2 das Gleiche wie oben. In wechselzuloop1 wird gewartet, bis der Taster losgelassen wird, danach springt der µC in AMPEL zurück.

__________________________
AMPEL
movlw .255
movwf PORTC
call delayloop1
movlw .0
movwf PORTC
call delayloop1

goto AMPEL

loop2
movlw .255
movwf PORTC

call delayloop2
call delayloop2
movlw .0
movwf PORTC
call delayloop2
call delayloop2

goto loop2
;-------------------------------------------------------------------
;Delay Routine

delayloop1
movlw .1
movwf delayA
loopA
movlw .256
nop
movwf delayB
loopB
btfss TRISA,3
goto wechselzuloop2
movlw .255
movwf delayC
loopC
decfsz delayC, f
goto loopC
decfsz delayB, f
goto loopB
decfsz delayA, f
goto loopA

return

delayloop2
movlw .1
movwf delayA
loopAA
movlw .255
nop
movwf delayB
loopBB
btfss TRISA,3
goto wechselzuloop1
movlw .255
movwf delayC
loopCC
decfsz delayC, f
goto loopCC
decfsz delayB, f
goto loopBB
decfsz delayA, f
goto loopAA
return

wechselzuloop1
movlw .255
movfw PORTC
movfw delayC
Schmidt1
decfsz delayC
goto Schmidt1
btfsc TRISA,3
goto AMPEL
goto wechselzuloop1

wechselzuloop2
movlw .255
movfw PORTC
movfw delayC
Schmidt2
decfsz delayC
goto Schmidt2
btfsc TRISA,3
goto loop2
goto wechselzuloop2

[ Diese Nachricht wurde geändert von: Peo am  1 Okt 2006 19:40 ]

[ Diese Nachricht wurde geändert von: Peo am  1 Okt 2006 19:41 ]

BID = 374186

Ltof

Inventar



Beiträge: 9347
Wohnort: Hommingberg

Ich bin jetzt gerade zu faul, die Programmstruktur nachzuvollziehen. Schau Dir mal die kommentierten Codeschnipsel in Ruhe an. Vielleicht hilfts ja.

Gruß,
Ltof


_________________
„Schreibe nichts der Böswilligkeit zu, was durch Dummheit hinreichend erklärbar ist.“
(Hanlon’s Razor)

BID = 374208

Peo

Gesprächig



Beiträge: 181
Wohnort: Baden-W.

Danke für das Programm.

Hier ist aber kein Flag gesetzt, so wie du das oben vorgeschlagen hast.

#define Taster TRISA,3 (TRISA,3 funktioniert anscheinend, da das Programm oben läuft) heißt doch nur, dass man statt TRISA,3 einfach Taster schreiben kann.

Bei der hier angehängten Programmstruktur wird ja immer nur zu Beginn des jeweiligen "Hauptprogramms" nach dem Taster gefragt. Ich bräuchte, auf Grund der Länge des Programms, dies aber ständig. Und da kommt das Flag wieder ins Spiel.

Das werde ich jetzt mal testen.

mfg

Peo

[ Diese Nachricht wurde geändert von: Peo am  1 Okt 2006 21:28 ]

BID = 374221

Ltof

Inventar



Beiträge: 9347
Wohnort: Hommingberg


Zitat :
Peo hat am  1 Okt 2006 21:26 geschrieben :

#define Taster TRISA,3 (TRISA,3 funktioniert anscheinend

Wenn das funktioniert, kann das nur ein Bug auf dem Chip sein! Das solltest Du Dir ganz schnell abgewöhnen und den Port korrekt abfragen! Beim nächsten PIC funktioniert das garantiert nicht mehr.

Zitat :

Hier ist aber kein Flag gesetzt, so wie du das oben vorgeschlagen hast.

Dann hast Du noch nicht alles gelesen.

_________________
„Schreibe nichts der Böswilligkeit zu, was durch Dummheit hinreichend erklärbar ist.“
(Hanlon’s Razor)

[ Diese Nachricht wurde geändert von: Ltof am  1 Okt 2006 22:09 ]

BID = 374224

Peo

Gesprächig



Beiträge: 181
Wohnort: Baden-W.

Danke für deine Tipps.

Ich habe gerade mit Flags gearbeitet, genauer mit einem Flag.
Funktioniert super und ist programmtechnisch fast kein Aufwand.
Das Schwierigste ist, bei den "Skip If" Abfragen den Überblick zu behalten, was wie übersprungen werden soll und was nicht, damit man das Flag auch richtig rauf und runter setzt.

Wenn ich jetzt mit zwei Flags arbeiten würde, könnte ich theoretisch vier Programme abspulen, mit drei Flags schon acht. Allerdings ist dann die Frage, ob ich die Logik hinter der Logik noch für mich umgesetzt bekomme

Nochmals Danke

mfg

Peo

BID = 374279

Ltof

Inventar



Beiträge: 9347
Wohnort: Hommingberg


Zitat :
Peo hat am  1 Okt 2006 22:10 geschrieben :

Wenn ich jetzt mit zwei Flags arbeiten würde, könnte ich theoretisch vier Programme abspulen, mit drei Flags schon acht.


In dem Beispiel sind beliebig viele Programme mit einem Flag abzuspulen. Es geht lediglich darum, den Tastendruck nicht zu vergessen.

Dabei ist es egal, ob, wie in dem Beispiel, von der Hauptschleife aus eins nach dem anderen Programm angesprungen wird, oder ob aus Programm1 bei erkanntem Tastendruck in Programm2 gesprungen wird, von 2 nach 3, von 3 nach 4 usw. Dafür reicht wirklich ein Flag.

Was Du beschreibst, ist ein Zustandszähler. Den würde man aber nicht mehr mit Bit-Abfragen auswerten, sondern durch Vergleiche mit Konstanten.

Zufällig habe ich ein paar 16F630 hier und habe Dein Programm auf PICkit2 (nachdem ich ein paar Initialisierungs-Zeilen hinzugefügt hatte) ausprobiert. Tatsächlich wechselt der PIC zwischen schnellem und langsamen Blinken auf Tastendruck. Was da passiert ist mir schleierhaft.

Nachdem das Proggi drauf ist, verweigert der PIC (oder PICkt2?) jegliche weitere Kommunikation. Da ist jemand zutiefst beleidigt.

Das geht erst wieder, nachdem ich den PIC mit PICstart gelöscht habe.

Welchen Datumscode haben Deine 16F630? Meine haben 051108V.

Gruß,
Ltof

_________________
„Schreibe nichts der Böswilligkeit zu, was durch Dummheit hinreichend erklärbar ist.“
(Hanlon’s Razor)

[ Diese Nachricht wurde geändert von: Ltof am  2 Okt 2006  8:16 ]

BID = 374285

Ltof

Inventar



Beiträge: 9347
Wohnort: Hommingberg

Das hätte ich auch gleich sehen können...

Die Abfrage von TRISA greift wegen der fehlenden Bankumschaltung tatsächlich auf PORTA zu. Deshalb funzt das.

@Peo
das sind zwei Fehler im Programm, die sich zufällig gegenseitig aufheben.

Viel Glück weiterhin!

Hoffentlich landen Deine Programme niemals in irgendwelchen sicherheitsrelevanten Systemen...

_________________
„Schreibe nichts der Böswilligkeit zu, was durch Dummheit hinreichend erklärbar ist.“
(Hanlon’s Razor)

BID = 374445

Peo

Gesprächig



Beiträge: 181
Wohnort: Baden-W.


Zitat :

Was Du beschreibst, ist ein Zustandszähler. Den würde man aber nicht mehr mit Bit-Abfragen auswerten, sondern durch Vergleiche mit Konstanten.


Was mich zur nächsten Frage bringt, wie vergleiche ich Konstanten?


Zitat :

Die Abfrage von TRISA greift wegen der fehlenden Bankumschaltung tatsächlich auf PORTA zu. Deshalb funzt das.


Das mit den Bänken habe ich auch noch nicht verstanden. Ich habe dies immer aus dem PICKIT Programm kopiert
Wozu ist das gut und woher weiß ich, in welche Bank ich schalten muss (du meinst doch sicher damit die Register-Banks/Pages?)


Zitat :

Hoffentlich landen Deine Programme niemals in irgendwelchen sicherheitsrelevanten Systemen...


Schlimmstenfalls zur Zugsteuerung auf einer Modelleisenbahn

Danke nochmal

anbei das "geflaggte" Programm. Es ist dank deiner Hilfe deutlich kürzer als das weiter oben.


mfg

Peo

_______________________


list p=16f630 ; list directive to define processor
#include <p16F630.inc> ; processor specific variable definitions

errorlevel -302 ; suppress message 302 from list file

__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.

VARIABLES UDATA_SHR
delayA RES 1
delayB RES 1
delayC RES 1
Flags equ 0x25 ;(oder eine andere freie Ram-Adresse)
#define Taster Flags,0


;**********************************************************************
RESET_VECTOR CODE 0x000 ; processor reset vector
goto main ; go to beginning of program

PROGRAM CODE
main
movwf OSCCAL ; update register with factory cal value
call 0x3FF ; retrieve factory calibration value
bsf STATUS,RP0 ; set file register bank to 1
movlw B'00000000'
movwf TRISA
movwf TRISC
bcf STATUS,RP0 ; set file register bank to 0
clrf PORTA
clrf PORTC
bcf Taster

loop1
movlw .255
movwf PORTC
call delayloop1
movlw .0
movwf PORTC
call delayloop1


goto loop1

loop2
movlw .255
movwf PORTC
call delayloop1
call delayloop1
call delayloop1
movlw .0
movwf PORTC
call delayloop1
call delayloop1
call delayloop1

goto loop2

;-------------------------------------------------------------------
;Delay Routine

delayloop1
movlw .1
movwf delayA
loopA
movlw .256
nop
movwf delayB
loopB
btfss PORTA,3
goto entprellen
movlw .256
movwf delayC
loopC
decfsz delayC, f
goto loopC
decfsz delayB, f
goto loopB
decfsz delayA, f
goto loopA
return


entprellen

btfsc Taster
call einsweniger

einsmehr
bsf Taster
call entprellenschleife

einsweniger
bcf Taster

entprellenschleife
movlw .255
movwf delayA
warten
decfsz delayA
goto warten
btfss PORTA,3
goto entprellenschleife
btfss Taster
goto loop1
goto loop2


;-------------------------------------------------------------------
END ; directive 'end of program'




[ Diese Nachricht wurde geändert von: Peo am  2 Okt 2006 19:41 ]

BID = 374538

Ltof

Inventar



Beiträge: 9347
Wohnort: Hommingberg


Zitat :
Peo hat am  2 Okt 2006 19:39 geschrieben :

Das mit den Bänken habe ich auch noch nicht verstanden.

Dieses und anderes elementare Grundwissen zu dem von Dir verwendeten µC einfach auszulassen, ist dreist!

Trotzdem ein lauffähiges Programm zu schreiben, oder besser: zu erschaffen, ist - hmm - ich würde es als höhere Kunst bezeichnen...

Zu den Banken (oder "Bänken"? - hat jemand einen Duden zur Hand?):
Das ist eine - häufig kritisierte - Eigenheit der PICs. Die Special-Function-Register, also die Speicherzellen zum Einrichten und Steuern der µC-eigenen Hardware (Ports, Timer, usw.) liegen in zwei Banken. Es gibt auch PICs mit nur einer Bank und womöglich auch mit mehr als zwei - das weiß ich jetzt nicht. Dazu sollte man jeweils das Datenlatt studieren. Bleiben wir bei dem 16F630.

Beispiel (bitte ausdrucken und aufmerksam lesen):
Das Register PORTA liegt an Adresse 05h in Bank0. Das Register TRISA liegt an Adresse 85h in Bank1. Ein direkter Zugriff dahin ist nicht möglich. Man muss dem µC vorher mitteilen, in welcher Bank das Register liegt, auf das man zugreifen will.

Das ist wie eine Reihe von Parkplätzen rechts und links der Fahrspur. Die Parkplätze links (Bank0) haben die Nummern 00h bis 1Fh und die Parkplätze rechts von 80h bis 9Fh (Bank1). Der Parkplatzzähler kann auf beiden Seiten nur von 0 bis 1F zählen. Das höchste Bit der Adresse existiert nur in der Bezeichnung der Parkplatznummer. Bekomme ich einen Parkplatz zugeteilt, so muss mein Navigationssystem neben der Parkplatznummer auch die Information über die Reihe (rechts oder links) bekommen. Bekomme ich den Parkplatz 85h (TRISA) zugeteilt. Der Wächter vergisst mir aber zu sagen, dass der in der rechten Reihe liegt, so lande ich in der linken Reihe auf Platz 05h (PORTA). Wenn es dumm läuft, stand da schon ein Auto, welches ich dann in den Graben schiebe. Das ist dann weg. Will das später jemand abholen, benutzt er mein Auto, welches nun auf "seinem" Platz steht.

Anders als im wirklichen Leben, sind die Autos nicht weg, wenn man sie abholt. Man benutzt quasi eine Kopie des Autos. Nur wenn vorher ein Auto falsch geparkt wurde, benutzt man eine falsche Kopie.

Die Flagge, die mir den Weg nach links oder rechts weist, ist das Bit RP0 im Register STATUS. Ist es auf 0, ist die linke Reihe gemeint, ist es auf 1, ist die rechte Reihe gemeint. Der Inhalt des Status-Registers ist in beiden Banken identisch. Deshalb funktioniert das überhaupt.

Du hast von TRISA gesprochen. Für das Funktionieren des Programmes war an der Stelle eigentlich PORTA gefragt. Da aber TRISA auf Bank0 angesprochen wurde (STATUS,RP0 war 0), wurde tatsächlich in BANK0 Adresse 05h angesprochen, also zufällig das richtige Register. Das war Glück!

Üblicherweise führt das Auslassen der Bankumschaltung zum Versagen des Programmes.

Schau mal in Kapitel 2.2.2 im Datenblatt, wo die Register alle liegen.

Du hast übrigens noch so einen künstlerischen Doppelfehler ohne Wirkung in Deinem Programm. Gleich die ersten beiden Programmzeilen! Das Register OSCCAL liegt in Bank 1. OSCCAL ist zum Kalibrieren der Taktfrequenz des internen Oszillators. In Adresse 0x3FF steht der Kalibrierwert für den internen Oszillator, damit er möglichst genau mit 4 MHz läuft. Das Holen des Kalibrierwertes (call 0x3FF) muss natürlich VOR dem Schreiben in OSCCAL gemacht werden und nicht danach! Und dann muss eben auch auf die richtige Bank geschaltet werden. Dein Oszillator läuft also mit einer unkalibrierten Frequenz. Wenn die genaue Frequenz unkritisch ist, merkt das keiner! Das Programm bleibt trotzdem lauffähig.

Gruß,
Ltof

_________________
„Schreibe nichts der Böswilligkeit zu, was durch Dummheit hinreichend erklärbar ist.“
(Hanlon’s Razor)

[ Diese Nachricht wurde geändert von: Ltof am  3 Okt 2006 10:05 ]


      Nächste Seite
Gehe zu Seite ( 1 | 2 Nächste Seite )
Zurück zur Seite 1 im Unterforum          Vorheriges Thema Nächstes Thema 


Zum Ersatzteileshop


Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum       Datenschutz       Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland       

gerechnet auf die letzten 30 Tage haben wir 22 Beiträge im Durchschnitt pro Tag       heute wurden bisher 28 Beiträge verfasst
© x sparkkelsputz        Besucher : 182653126   Heute : 8200    Gestern : 6686    Online : 145        2.1.2025    23:00
5 Besucher in den letzten 60 Sekunden        alle 12.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
xcvb ycvb
0.0544860363007