Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

10mS an jedem Rechner
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
triti



Anmeldungsdatum: 23.04.2009
Beiträge: 44

BeitragVerfasst am: 23.04.2009, 13:23    Titel: 10mS an jedem Rechner Antworten mit Zitat

Hi,
ich habe am LPT einen bipolaren Schrittmotor: OUT 888,1, call pause, OUT 880,4, call pause und so weiter. Geht super.
Zwischen den OUTs braucht man ja eine Zeitverzögerung - call pause.
Das geht am einfachsten mit:

sub pause
for I= 1 to .... : next I
exit sub

Damit das aber an anderen PCs gleich ist und der Interpreter beim ausprobieren auch langsamer ist als die exe hab ich mir gedacht dass man am Anfang die Zählgeschwindigkeit vom Rechner prüft und daraus etwa 10 mS für die Pause ausrechnet:

DO
TIMER ON
ON TIMER(2) GOSUB weiter:

FOR I# = 1 TO 1D+16
x# = x# + 1
NEXT I#
LOOP

weiter:
timer off
pause= FIX(x# / 200) 'soll ca. 10mS sein
print pause
x# = 0: I# = 0


1) Ist das so vernünftig, oder wie macht mans besser?
2) Passen 10 mS Pause für einen Schrittmotor? Wie lang soll so eine Pause sein?

lg
Triti
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 23.04.2009, 15:28    Titel: Antworten mit Zitat

Zitat:
2) Passen 10 mS Pause für einen Schrittmotor? Wie lang soll so eine Pause sein?
Das passt man eigentlich an die Drehgeschwindigkeit des Steppers an.
Anfahren = kleine Winkelgeschwindigkeit -> längere Pause,
Schnellauf = hohe Winkelgeschwindigkeit -> kürzere Pausen,
bremsen/halten = Winkelgeschwindikeit ~0 -> keine Pausen.
Zitat:
1) Ist das so vernünftig, oder wie macht mans besser?
Ich hoffe du betreibst dies unter echtem DOS nicht unter WinDOS grinsen
Windows gibt die IN/OUT Befehle nicht zeitgerecht weiter, da dies durch interne Routinen (Multitasking) verzögert werden kann.
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
isiprimax



Anmeldungsdatum: 02.01.2009
Beiträge: 77

BeitragVerfasst am: 23.04.2009, 15:48    Titel: Antworten mit Zitat

Ich würde das mit Timer machen.

Code:

dim as double start

start = timer

do:loop until timer > (start + 1)   ' 1 = 1 sek




mfg
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 23.04.2009, 16:12    Titel: Antworten mit Zitat

falsche antwort. timer hat eine auflösung von höchstens 55ms.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Flo
aka kleiner_hacker


Anmeldungsdatum: 23.06.2006
Beiträge: 1210

BeitragVerfasst am: 23.04.2009, 17:11    Titel: Antworten mit Zitat

da gabs doch mal irgendwo auf qbasic.de n msecwait oder sowas... ich glaub das hat auch mit forschleifen gearbeitet... such einfach mal...
_________________
MFG
Flo

Satoru Iwata: Wer Spaß am Spielen hat, fragt nicht nach Grafik.

zum korrekten Verstaendnis meiner Beitraege ist die regelmaessige Wartung des Ironiedetektors unerlaesslich.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 23.04.2009, 17:31    Titel: Antworten mit Zitat

Mit For-Schleifen Zeit zu messen ist ziemlich billig und geht auch nur unter reinem DOS...
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
triti



Anmeldungsdatum: 23.04.2009
Beiträge: 44

BeitragVerfasst am: 23.04.2009, 20:06    Titel: Antworten mit Zitat

Hi,

> Ich hoffe du betreibst dies unter echtem DOS nicht unter WinDOS
Na sicher doch. Bin ja anständig lächeln

> Das passt man eigentlich an die Drehgeschwindigkeit des Steppers an.
> Anfahren = kleine Winkelgeschwindigkeit -> längere Pause,....
Yep, genau darum gehts: bei welchen U/Min. wieviel Pause?

> Windows gibt die IN/OUT Befehle nicht zeitgerecht weiter, da dies durch interne Routinen (Multitasking) verzögert werden kann.
Äh, auch mit userport.sys nicht? Schau schau. Hab ich nämlich gerade installiert aber noch nicht ausprobiert.

> timer hat eine auflösung von höchstens 55ms.
Eben.

> msecwait oder sowas... ich glaub das hat auch mit forschleifen gearbeitet... such einfach mal...
Hab ich doch und auch was gefunden. Die sagen, das ist eine Notlösung, funktioniert aber.
Nur: Ich will es halt wenn schon dann genau und an die Rechner angepasst.
Also weil keiner meckert denk ich, dass das mit der for-Schleife so o.k. ist.

lg
Triti
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 23.04.2009, 21:44    Titel: Antworten mit Zitat

Zitat:
bei welchen U/Min. wieviel Pause?
ist ganz abhängig vom Steppertyp und Last. Hier sind Grundlagen:
http://www.roboternetz.de/wissen/index.php/Schrittmotoren

Oft hilft "einfach ausprobieren".

Zitat:
Äh, auch mit userport.sys nicht?
Unter 95/98/ME kannst du noch auf die Ports zugreifen, nicht zeitgerecht aber direkt.
Unter NT/W2k/XP/Vista geht das nur noch über SYS-Treiber, auch nicht zeitgenau und mit Umweg über den Treiber missbilligen .

Wobei ich aber schätze das sich das im Rahmen von unter 1ms abspielt.

EDIT/
noch ein Link zum testen von Steppern:
http://www.roboternetz.de/phpBB2/files/rotorlastwinkel.pdf
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.


Zuletzt bearbeitet von volta am 24.04.2009, 11:39, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
triti



Anmeldungsdatum: 23.04.2009
Beiträge: 44

BeitragVerfasst am: 23.04.2009, 22:39    Titel: Antworten mit Zitat

Dank für den Link! Wird dauern bis ich das alles komplett verstehe.

Ähem, gibts irgendwo einen Anleitung, wie man eine Strombegrenzung bastelt? Mein Motor wird nämlich mächtig heiss, wenn er steht. Ich suche eine Möglichkeit, wie ich so eine einfach dazu/dazwischenschalte, wenn der Motor in Warteposition ist. So, dass der Motor aber nicht die ganze Haltekraft und auch nicht die Position verliert. Brutal umlenken mit einem Umschaltrelais auf einen dicken Widerstand?

lg
Triti
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 24.04.2009, 12:15    Titel: Antworten mit Zitat

Hallo

Jojo hat Folgendes geschrieben:
falsche antwort. timer hat eine auflösung von höchstens 55ms.


Na ja, standardmäßig schon. Unter DOS kann man den Timer aber schneller laufen lassen. Eine Auflösung von 10 ms bekommt man mit

Code:
OUT 67, 52    'Timer-Steuerregister: Timer 0, Low- und Highbyte, Modus 2
OUT 64, 154   'Lowbyte
OUT 64, 46    'Highbyte


Zur Einstellung des Timer-Steuerregisters siehe hier.

Im Timer sitzt ein 16 Bit Teiler, der mit 1,193 MHz getaktet wird. Mit dem Low- und Highbyte kann man das Teilerverhältnis aber einstellen.

Auf die Werte für Low- und Highbyte kommt man so. Normalerweise läuft der Timer mit einer Auflösung von 2^16 Takten pro Stunde. Macht 65536 Takte / 3600 Sekunden = 18,204 Hz bzw. 54,9 ms Periodendauer.

Will man 100 Hz bzw. 10 ms Auflösung, muss man den Timer 100/18,204 = 5,493 mal schneller laufen lassen. Also teilt man 65536 durch 5,493. Ergibt ein Teilerverhältnis von 11930. Die zerlegt man in zwei Byte und kommt so auf einen Wert für das Highbyte von 46 und das Lowbyte ist 154.

46 * 256 + 154 = 11930.

Will man z.B. 5 kHz Taktrate bzw. 200 µs Periodendauer schreibt man folglich:

Code:
OUT 67, 52    'Timer-Steuerregister: Timer 0, Low- und Highbyte, Modus 2
OUT 64, 239   'Lowbyte
OUT 64, 0     'Highbyte


Eine Warteschleife sieht dann z.B. so aus:

Code:
warteschleife:
DO
 tneu = TIMER
LOOP WHILE tneu = talt
talt = tneu
RETURN


So kann man den Timer auf jede gewünschte Taktrate umstellen. Langsamer geht natürlich nicht, weil man nur durch maximal 2^16 teilen kann. Der große Vorteil gegenüber Zählschleifen ist aber, dass es egal ist, was außerhalb der Warteschleife passiert, die Zeitabstände bleiben immer gleich lang. Vorausgesetzt, es dauert nicht länger als eine Timerperiode. Und diese Methode sollte auf jedem Rechner laufen.

Gruß
Skilltronic

EDIT: Fehler im Beispiel für 5kHz korrigiert. Siehe zweite Seite dieses Threads.
_________________
Elektronik und QB? www.skilltronics.de !


Zuletzt bearbeitet von Skilltronic am 15.05.2009, 20:48, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
triti



Anmeldungsdatum: 23.04.2009
Beiträge: 44

BeitragVerfasst am: 25.04.2009, 20:08    Titel: Antworten mit Zitat

Danke Skilltronic!
Das heisst, man kann den Rechner-Timer von Anfang an auf z.B. 10mS einstellen und das bleibt dann bis man ihn abschaltet - oder nur, bis das Programm beendet ist?
Weil wenn ich danach ein anderes (altes) Programm mit einem normalen Timer-Befehl laufen lassen, stimmen die Zeiten nicht mehr. Muss man also am Programmende den Timer schlauerweise wieder auf 55mS zurückstellen?

Beim Starten wird der PC auf diese 55mS eingestellt - warum nicht gleich auf 10mS? Wäre doch egal und damit wärs doch oft praktischer?

Für Noobs wie mich:
Das braucht man also nur am Programmanfang (hier 10mS):
OUT 67, 52 :OUT 64, 154 :OUT 64, 46

Und das kann überall im Programm stehen (hier vergrössert auf 30mS):
warteschleife:
DO
tneu = TIMER
LOOP WHILE tneu = talt +0.02 'Wartezeit wäre dann 30mS
talt = tneu
RETURN


So, jetzt hab ich mich da endlich durchdividiert und kapiert wie mans rechnet aber verstehen ist nicht.
> 46 * 256 + 154 = 11930.
Wenn Dir die Antwort nicht zu langweilig ist: WARUM teilt man das auf diese Art in low/high byte? Wieso kommt da high und low raus?

> Zur Einstellung des Timer-Steuerregisters siehe hier.
Ist mir echt zu hoch, sorry. Wird aber sicher Schlaueren helfen.

lg
Triti
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4701
Wohnort: ~/

BeitragVerfasst am: 25.04.2009, 21:09    Titel: Antworten mit Zitat

Das ist nicht die Methode, um Low- und High-Byte zu bekommen, sondern das Ergebnis.
Code:
low = wert and 255
high = wert shr 8


edit: muss natürlich Byte statt Bit heißen
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.


Zuletzt bearbeitet von nemored am 25.04.2009, 22:38, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
triti



Anmeldungsdatum: 23.04.2009
Beiträge: 44

BeitragVerfasst am: 25.04.2009, 22:04    Titel: Antworten mit Zitat

@ nemored
?......... mit dem Kopf durch die Mauer wollen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4701
Wohnort: ~/

BeitragVerfasst am: 25.04.2009, 22:36    Titel: Antworten mit Zitat

Hmm ... was High- und Lowbyte ist, ist klar? Wenn eine Zahl aus zwei Byte, also 16 Bit besteht (z. B. binär 1001101101110101), dann ist der grüne Anteil das Lowbyte. Das bekommst du am einfachsten mit AND 255 (binär 0000000011111111). Binär geschrieben:
Code:
    1001101101110101
AND 0000000011111111
=   0000000001110101

Mit SHR 8 schiebst du eine Zahl um 8 Bit nach rechts, also fallen die grünen Ziffern weg und es bleiben nur die blauen übrig.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
triti



Anmeldungsdatum: 23.04.2009
Beiträge: 44

BeitragVerfasst am: 26.04.2009, 18:49    Titel: Antworten mit Zitat

> ... was High- und Lowbyte ist, ist klar?
Klar ist übertrieben aber jetzt ist es zumindest heller.

> Mit SHR 8 schiebst du eine Zahl um 8 Bit nach rechts, also fallen die grünen Ziffern weg und es bleiben nur die blauen übrig.
Aha. Na gut, wenn man das halt so macht....

Warum dividiert Skilltronic dann durch 256 und nicht durch 255? Und warum überhaupt 16? Hat das was mit 2^16 Takten pro Stunde zu tun? Aber ich glaube dass ich das nicht so schnell verstehen werde und will hier nicht weiter herumnerven. Die Methode hab ich ja kapiert, die Grundlagen noch lange nicht. Es funktioniert, das ist das wichtigste.
Danke für die Auskunft.

lg
Triti
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4701
Wohnort: ~/

BeitragVerfasst am: 26.04.2009, 20:22    Titel: Antworten mit Zitat

Wie Skilltronic das ausgetüftelt hat, weiß ich nicht; mit OUT habe ich mich nie beschäftigt und kann dazu nichts sagen. Die Sache mit dem Teilen und dem SHR hat auch nicht direkt etwas damit zu tun sondern wird nur gebraucht, um zu sehen, was man wohin OUTen muss.

Beim (Integer-)Teilen durch 256 passiert auf jeden Fall dasselbe wie bei SHR 8 (nur ist zweites etwas schneller). Klarer wird das bei Zahlen im Binärformat:
Teilen durch 2 (dezimal; bzw. teilen durch 10 binär) heißt, dass die Ziffer ganz rechts wegfällt. Dasselbe passiert bei SHR 1
Code:
PRINT BIN$(&b10010010 \ 2)    ' Ergebnis: 1001001
PRINT BIN$(&b1001001 \ 2)     ' Ergebnis: 100100


Beim Teilen durch 4 (2^2; binär 100) fallen 2 rechte Ziffern weg, beim Teilen durch 8 (2^3; binär 1000) sind es 3 Ziffern usw.; das Teilen durch 256 (2^8; binär 10000000) verwirft dann also 8 Ziffern und bewirkt dasselbe wie SHR 8. Beim Teilen gehe ich natürlich immer davon aus, dass mich Nachkommastellen nicht interessieren; deswegen auch Teilung mit Backslash statt mit Slash.

Das mit der 255 ist eine klein wenig andere, wenn auch ähnliche Sache: die ersten acht Ziffern ergeben die Zahlen 0-255. Mit AND 255 werden alle Ziffern jenseits der achten Stelle "weggeworfen" und nur die ersten 8 Ziffern behalten.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
triti



Anmeldungsdatum: 23.04.2009
Beiträge: 44

BeitragVerfasst am: 27.04.2009, 13:49    Titel: Antworten mit Zitat

Aha!
Das verstehe ich.
Danke!

Aber etwas fällt mir gerade ein: Wenn der Timer 5x schneller läuft, hat man da nicht auch 5x früher das "Mitternachtsproblem"? Soll heissen, wenn eine Maschine über viele Stunden angesteuert wird (so will ich das nämlich), geht das nur wenn man im Programm eine Absicherung dafür einbaut, dass der Zähler wieder von vorne anfängt.
Bei der viel weniger schlauen Zählmethode fällt dieses Problem überhaupt weg.

lg
Triti

edit:
Moment, ist das nicht so:
wenn man schreibt
LOOP WHILE tneu = talt
machts nichts, weil sich die Zeit egal in welche Richtung ändert. Man muss also den Timer genau auf die gewünschte Zeit einstellen.

Schreibt man aber
LOOP WHILE tneu = talt +0.02 'Wartezeit wäre dann 30mS
dann hat man das Mitternachtsproblem.

Oder man stellt den Timer am Anfang der Schleife immer auf Null.

Hmm...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 27.04.2009, 15:11    Titel: Antworten mit Zitat

triti hat Folgendes geschrieben:
Moment, ist das nicht so:
wenn man schreibt
LOOP WHILE tneu = talt
machts nichts, weil sich die Zeit egal in welche Richtung ändert. Man muss also den Timer genau auf die gewünschte Zeit einstellen.


Ja, das ist so. Deshalb habe ich es auch so gemacht zwinkern

triti hat Folgendes geschrieben:
Schreibt man aber
LOOP WHILE tneu = talt +0.02 'Wartezeit wäre dann 30mS
dann hat man das Mitternachtsproblem.


Nicht nur das, es geht so überhaupt nicht. Denn TIMER ändert sich nie um genau 0,02, tneu ist also nie genau gleich talt + 0,02. Wenn schon, müsstest du es mit > machen. Dann bleibt aber immer noch das Mitternachtsproblem, weshalb die erste Methode auch besser ist. Willst Du eine andere Taktrate, solltest du einfach den TIMER anders einstellen.

Ich versuche heute Abend noch einmal, das alles etwas ausführlicher zu erklären, im Moment habe ich leider keine Zeit. Auf 30ms kommst du jedenfalls mit

Code:
OUT 67,52
OUT 64, 207
OUT 64, 139


Gruß
Skilltronic
_________________
Elektronik und QB? www.skilltronics.de !
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2529
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 27.04.2009, 21:13    Titel: Antworten mit Zitat

Jojo hat Folgendes geschrieben:
Mit For-Schleifen Zeit zu messen ist ziemlich billig und geht auch nur unter reinem DOS...

...wobei diese Methode selber unter reinem DOS bei modernen CPUs mit Vorsicht zu geniessen ist: Der heutzutage überall standardmässig vorhandene Cache macht das lineare Verhalten vollkommen zunichte!

Früher auf einem Commodore 64 sowie IBM PC/XT mit Intel 8088-Prozessor waren solche Schleifen noch vollkommen in Ordnung, weil man die Anzahl benötigten Taktzyklen noch genau berechnen konnte, da es dort zwischen CPU und RAM keinerlei schnelle Zwischenspeicher gab.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 28.04.2009, 13:29    Titel: Antworten mit Zitat

Hallo

triti hat Folgendes geschrieben:
Das heisst, man kann den Rechner-Timer von Anfang an auf z.B. 10mS einstellen und das bleibt dann bis man ihn abschaltet - oder nur, bis das Programm beendet ist?
Weil wenn ich danach ein anderes (altes) Programm mit einem normalen Timer-Befehl laufen lassen, stimmen die Zeiten nicht mehr. Muss man also am Programmende den Timer schlauerweise wieder auf 55mS zurückstellen?


Der veränderte Einstellung es Timers bleibt (unter DOS) nach beenden des Programms tatsächlich erhalten. Ich habe es eben ausprobiert und war selbst überrascht. Im Prinzip ist es aber eigentlich logisch, weil man ja an der Hardware herumstellt. Man kann den Timer aber mit

Code:
OUT 67, 52
OUT 64, 0
OUT 64, 0


in den Standardzustand zurückstellen.

triti hat Folgendes geschrieben:
Beim Starten wird der PC auf diese 55mS eingestellt - warum nicht gleich auf 10mS? Wäre doch egal und damit wärs doch oft praktischer?


Warum nicht auf 1ms oder 100ms? Was praktischer ist, ist relativ. Man hat sich eben irgendwann in grauer Computervorzeit auf die 2^16 Takte pro Stunde festgelegt.

triti hat Folgendes geschrieben:
Für Noobs wie mich:
Das braucht man also nur am Programmanfang (hier 10mS):
OUT 67, 52 :OUT 64, 154 :OUT 64, 46


Ja, die Einstellung bleibt erhalten, bis man sie wieder ändert. Wie wir jetzt wissen, sogar über das Ende des Programms hinaus. Die Warteschleife kann dann natürlich überall stehen.

triti hat Folgendes geschrieben:
So, jetzt hab ich mich da endlich durchdividiert und kapiert wie mans rechnet aber verstehen ist nicht.
> 46 * 256 + 154 = 11930.
Wenn Dir die Antwort nicht zu langweilig ist: WARUM teilt man das auf diese Art in low/high byte? Wieso kommt da high und low raus?


Das mit dem High- und Lowbyte ist nur so eine Hilfskrücke. Der Teiler, der den Takt auf 18,2 Hz herunterteilt hat 16 Bit, also zwei Byte. Mit OUT kann man aber immer nur einzelne Bytes (acht Bit) übergeben, das ist eben so. Deshalb teilt man die 16 Bit in zwei "Portionen" auf.

Vielleicht wird es mit dieser kleinen Grafik verständlicher.



Die Quarzzeitbasis liefert immer eine Frequenz von 1193047 Hz. Das ist bei allen Rechnern so und daran lässt sich auch nichts ändern. Interessant ist der 16 Bit Binärzähler. Der zählt mit jedem Impuls vom Quarz um eins runter. Jedoch kann er nicht in den negativen Bereich hineinzählen, Vorzeichen kennt dieser einfache Zähler nicht. Wenn er also bei Null angekommen ist, springt er wieder auf einen gegebenen Startwert zurück, man sagt, er läuft über.

Jedes mal wenn der Zähler überläuft, sendet er er wiederum einen Impuls. Dieser ist die Basis für den TIMER. So funktioniert auch das Herunterteilen. Im Standardzustand springt der Zähler beim Überlauf von Null auf den Startwert 65535 zurück, den höchsten Wert, den man mit 16 Bit darstellen kann und sendet sein Überlaufsignal. Er zählt wieder runter auf Null, sendet wieder einen Überlaufimpuls usw. Also alle 65536 Impulse der Quarzzeitbasis wird ein Überlaufimpuls gesendet und der Takt so durch 2^16 geteilt.

TIMER erwartet diesen Standardzustand und zählt die "innere Uhr" des Rechners jedes mal, wenn er einen solchen Überlaufimpuls erkennt um 54,9 ms weiter, 65536 dieser Überlaufimpulse ergeben so eine Stunde.

0,0549s x 65536 = 3600s

Genau diesen Startwert, auf den der Zähler zurückspringt, kann man jetzt mit OUT einstellen. Setzt man ihn z.B. auf 9999, wird nach dem Runterzählen auf 0 wieder bei 9999 angefangen und der Quarztakt so durch 10000 geteilt. Die Null zählt ja immer mit, deshalb 9999 für ein Teilerverhältnis von 10000 zu 1.

Welches Teilerverhältnis man für eine beliebige Timerfrequenz braucht, kann man also auch anders ausrechnen. Nehmen wir z.B. 30ms. das sind 0,03 Sekunden. Die multipliziert man einfach mit der Frequenz der Quarzzeitbasis.

1193047 x 0,03 = 35791,41

Das Teilerverhältnis ist also in diesem Fall 35791, weil nur mit ganzen Zahlen gearbeitet wird. Davon muss man noch 1 abziehen, weil die Null ja mitzählt. Das hatte ich in meinem letzte Beitrag vergessen.

Das muss nun noch in High- und Lowbyte geteilt. Das mit dem SHR ist ja gut und schön, nur gibt es diesen Befehl in QBasic nicht. Man könnte es so berechnen:

Code:
INPUT "Gewuenschte Timeraufloesung in Millisekunden: ", milli!
teiler& = 1193.047 * milli!
IF teiler& > 65534 THEN PRINT "Aufloesung zu gross"
IF teiler& < 1 THEN PRINT "Aufloesung zu klein"
highbyte% = FIX(teiler& \ 256)
lowbyte% = teiler& - highbyte% * 256& - 1
PRINT "Lowbyte:"; lowbyte%
PRINT "Highbyte:"; highbyte%


Das mit dem zu groß / zu klein kommt daher, dass man nicht durch mehr als 65536 und nicht durch weniger als 2 teilen kann. Die maximale Auflösung sind die standardmäßigen 54,9ms, Minimum sind 1,67µs.


triti hat Folgendes geschrieben:
Ist mir echt zu hoch, sorry. Wird aber sicher Schlaueren helfen.


Hat mit schlau nicht viel zu tun sondern damit, wie lange man sich damit schon beschäftigt.

So, das war jetzt sehr ausführlich. Ich hoffe, damit wird das Ganze etwas klarer.

Gruß
Skilltronic
_________________
Elektronik und QB? www.skilltronics.de !
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz