Forum: Mikrocontroller und Digitale Elektronik Mega16,Bascom:zu schnell für vergleich?


von Manuel (Gast)


Lesenswert?

Hallo leute,

ich habe da mit einem kleinem problem zu kämpfen: betreibe den mega16
mit den internen 8mhz und erhöhe per timer alle 0,0001s eine zahl um
eins....wenn dann die zahl gleich x ist (also 10.000 oder so) dann soll
etwas passieren (led blinken, irgendwas am lcd ausgegeben
werden)...aber nichts passiert. erst wenn ich sage, wenn die zahl
größer als 10.000 ist,dann passiert auch das gewünschte..

setze ich nun den timer runter,so das nun alle 0,001 sek der zähler
erhöht wird, dann klappt das auch mit dem vergleich...was kann das
sein?

also bei 0,0001 sek geht das nicht:

if x =10000 then mach was

es geht nur:
if x> 10000 then mach was
oder
if x< 10000 then mach was

bei 0,001 sek geht

if x =10000 then mach was


ist das nun ein bascom problem oder generell?

mit der allgemeinen programmierung in bascom bin ich vertraut, also
kann es dran nicht liegen.

auch ist mir aufgefallen,daß die genauigkeit beim betrieb sich erst
nach einer gewissen zeit einstellt:

ich toggle ein port alle 0,001 sek und lese die zeit über timer0 mit T0
aus.paralell dazu messe ich die gesamtzeit. nun sollte mann denken, daß
das verhältnis von dem getoggelten port und der gesamtzeit 2:1 ist (der
port ist ja mal high und mal low, somit wird nur 50% erfasst was ja 2:1
ist). aber pustekuchen, laut meinem display ist es in den ersten 10sek
2,04:1 und schwingt sich dann auf die 2:1 ein....hat dafür einer ne
erklärung? liegt es am internen quarz?

von Dieter B. (Gast)


Lesenswert?

Hallo

Wie immer, ohne Prgramm keine Hilfe möglich. Ist doch wirklich so
schwer, das Programm daran zu hängen oder.

Arbeitest du mit Interrupts, dann muß man mal genau überlegen, wann die
aufgerufen werden können. Da kann schon viel schief laufen.

Abfrage aud "gleich" bringt halt schon mal Fehler, bei denen mann
graue Haare bekommen kann. Habe ich mir komplett abgewöhnt. Lieber
Abfrage mit < oder > , wenns denn geht.

MFG
Dieter

von crazy horse (Gast)


Lesenswert?

kommt einfach drauf an, ob in der Zeit, in der die Variable getestet
wird, auch tatsächlich dieser Zählerstand überhaupt auftritt.
Mögliche Ursachen:
-CPU treibt sich in anderen Interrupts rum, nach reti steht schon
wieder ein Timerint an, wird dann auch gleich ausgeführt, danach ist
der Zählerstand 10.000 schon wieder futsch
-Programmlaufzeit zwischen den Abfragen so lang, dass die Abfrage nicht
bei jedem Timerstand erreicht wird.
Und dann gibt es noch ein ganz übles Problem: eine 16bit-Variable kann
nur in 2 Schritten getested werden. Wenn nun genau zwischen diesen 2
Schritten der Int auftritt, kann das Vergleichsergebnis falsch werden.
Unwahrscheinlicher Fall, aber möglich. Und alles, was möglich ist,
passiert auch irgendwann mal. In kritischen Anwendungen müssen solche
Fälle auf jeden Fall beachtet werden.

von Manuel (Gast)


Lesenswert?

@dieter
"Wie immer, ohne Prgramm keine Hilfe möglich. Ist doch wirklich so
schwer, das Programm daran zu hängen oder."

nö,aber sinnlos. es sei denn, du möchtest code von mir mopsen *g

@crazy horse also einzig die beiden timerinterrupte laufen  bei mir.
die vergleichsabfrage ist in der normalen  do-loop schleife im
hauptteil
und außer  2 kleinen if-schleifen (die aber gar nicht angelaufen, da
eintrittsbedinungen nicht erfüllt sind) ist kein weiterer code
vorhanden (okay, die lcd-sachen schon) und die zählvariable ist integer
bei mir

ist halt nur komisch, daß es dies problem beim verlangsamen des
counters
nicht gibt. würde da assembler abhilfe schaffen?

von crazy horse (Gast)


Lesenswert?

Dieter hat aber recht, ohne Programm kann man nicht viel sagen, wo die
Zeit vertrödelt wird. und bei 100µs Timerint bleiben ja nur 800 Takte,
nicht unbedingt zu wenig, aber es vertut sich auch ziemlich schnell,
allein schon der Aufruf der Int, das Sichern der Register (meist zu
viele), das Nachladen des Timerregister, das Incrementieren der
Variablen, alles gesicherte wieder zurückholen und der return - da
können schon schnell 100 oder mehr Takte verbraten sein. Und wenn dann
noch ein anderer Int dazu kommt, kann es eben schnell zu deinen
Problemen kommen.
Und im Ernst: ich glaube nicht, dass sich hier irgendjemand für deine
Geheimnisse interessiert.

von Bernd Schmidt (Gast)


Lesenswert?

Um den Interrupt auszuschließen einfach mal denselben vor der Abfrage
disablen.

Also:
Disable Interrupts
If irgendwas then sonstwas
Enable Interrupts

Damit sollte eventuell wenigstens der Vergleich mit "="
funktionieren.
Machmal hilft auch der Vegleich über eine zweite Variable.

Bernd

von Stefan Kleinwort (Gast)


Lesenswert?

Die Leute, die hier scharf auf Code sind, schauen sicher lieber in die
Codesammlung als in die vermurksten Programme Hilfesuchender.

uch den Fehler lieber in Deinem Programm, Bascom mag zwar lahm sein,
aber so lahm auch wieder nicht.

Stefan

von Peter D. (peda)


Lesenswert?

"wenn die zahl größer als 10.000 ist,dann passiert auch das
gewünschte.."


Das ist doch auch die übliche Vorgehensweise.

Willst Du auf Gleicheit testen, dann must Du komplett den ungünstigsten
Fall durchrechnen, d.h. daß auch mit Sicherheit mindestens 1 Vergleich
bei jedem Zählerwert stattgefunden haben kann.

In Deinem Fall wird warscheinlich 1 Vergleich bei 9.999 erfolgen und
der nächste aber erst bei 10.001 bedingt durch die dazwischen
vergangene Rechenzeit.


Peter

von nix (Gast)


Lesenswert?

Ich tippe mal auf einen Fehler vom Typ
if (x = 10000)
statt
if (x ==10000)
Bei > oder < gibt es das halt nicht!

Zumindest bei C gibt es da einen Unterschied. Nach dem Fehler sucht man
meist lange (zumindest beim 1. mal). Da man immer das liest was man
lesen will.
Ob die Syntax bei deinem Basic auch so ist weiß ich nicht, aber einen
Versuch ist es wert.

von Ratber (Gast)


Lesenswert?

"nö,aber sinnlos. es sei denn, du möchtest code von mir mopsen *g"


Au ja ,auf dein Fehlerhaftes Programm hat die Welt gewartet.

Laß mich raten:

Radio
Stoppuhr.
Uhr.
Uhr mit Stopuhr
Uhr mit Stopuhr und Radio
Uhr mit Stopuhr ,Radio und DCF-Zeitbasis
Irgendein Lichterzirkus
Modellbahnsteuerung
Heizungssteuerung
Garagenlichtsteuerung
Alarmanlage
Futterautomat für Fische
Futterautomat für Hund
Futterautomat für Katze
Futterautomat für Goldhamster
Futterautomat für Kaninchen
Futterautomat für Frau
Futterautomat für Kinder
Futterautomat für Oma
Futterautomat für Opa
Satelitenschüsselrotor
Irgendein Messgerät
(Spannung,Strom,Leistung,Temperatur,Strahlung,Faulgase,Kippen,Alkohol-
bzw. Drogenkonsum usw.)
Lüftersteuerung
Waküsteuerung
Drehzahlregler allgemein,Speziell und Übersinnlich
Akkulader
Akkuentlader
Akkucontroller
Zeitschalter
Onlinetimer
Oooooder Schwiegermutterzähler.

Es gibt soviele Projekte die es Tausendemal gibt als Zick nich gleich
rum.
Warum ist fast immer die erste Frage bei Controllern die nach dem
Copybit ?


Wie wärsstatt "If X=10000 Then" mit "If X>9999 Then" ? ;-)

von ape (Gast)


Lesenswert?

wenn du so scharf auf die exakten 10000 bist dann teste den timer auf >=
10000 und setze ihn danach nicht auf 0 sondern ziehe 10000 ab.

Und wenn den Programm wirklich so ultra geheim ist, und absolut
revolutionäre Ziele erfolgt (ich tippe ja auf den Futterautomat für
Oma/Opa rofl) dann könntest du deinen Code auch so weit reduzieren
das er nichts weiter tut als den Fehler zu erzeugen. Manchmal findet
sich dabei dann auch der Fehler.

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.