PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ich brauche einen Tip für Bascom



Halodri
06.12.2010, 16:46
Hallo!

Nachdem mein kleines Werk nun funktioniert wie es soll habe ich mich mal wieder auf dünnes Eis begeben und mich mit Timer1 versucht.

Erst hab ich mal eine Diode blinken lassen um zu sehen das auch alles richtig funktioniert. Tut es auch.

Jetzt hab ich natürlich in der Sprungmarke Timer_irq
meine eigenen Sachen getippelt und zwar Sachen wie ein Zähler und ne Variable auf 1 setzen.

Lange Rede kurzer Sinn wie bekomme ich Bascom im Simulator dazu mir
ZB. Den Zähler den ich nach der Sprungmarke zählen lasse anzuzeigen.
Bzw. mit F8 diese Schritte durch zu klappern?
Der Haken bei SIM Timers ist drin.

Und wenn ich grad dabei bin.

Ich habe gedacht das wenn ich folgende Zeilen im Programm drin stehen habe der µC nicht nur mit 1Mhz läuft...
$regfile = "m48def.dat"
$crystal = 8000000

Oder hab ich da einen Denkfehler?


Danke schon mal für Eure Hilfe...

Grüße aus dem Süden

Jaecko
06.12.2010, 17:49
#1) Irgendwo sollte es eine Möglichkeit geben, eine Variable zu einem "Watch-Window" hinzuzufügen. Weiss jetzt nicht auswendig, wie das bei Bascom heisst. Aber da gabs glaub ich sogar 4 verschiedene Watch-Windows.

#2) Die $Crystal-Angabe ändert an der Taktfrequenz des Controllers nichts. Die sagt dem Programm nur, wie schnell er läuft.
D.h. diese Angabe muss mit dem wahren Takt übereinstimmen, ausser man will absichtlich Warteschleifen/etc. schneller/langsamer laufen lassen.
In deinem Fall (1MHz wahr, 8MHz angegeben) werden Warteschleifen & Co. 8x langsamer laufen.
Die Taktfrequenz wird über die Fusebits geändert. Hierbei aufpassen, da kann man sich schnell mal aus dem Controller aussperren.

Halodri
06.12.2010, 19:00
Hallo!

An die Fusebits wage ich mich irgendwann mal dran. Das reicht noch wenn ich mir sicherer in dieser MAterie bin. Hab jetzt erst mal
$Crystal = 1000000 rein genommen damit keine Missverständnisse mehr aufkommen.

Also ich komme mit diesem Timer Zeugs nicht klar. Hinter mir blinkt eine Leuchtdiode seit 2 Stunden im Sekundentakt.
Also die Funktion sollte gegeben sein..

Folgendes habe ich im Prog drin...

On Timer1 Timer_irq
Const Timervorgabe = 65500 'dieser hohe Wert ist nur zu Testzwecken.'
Enable Timer1
Enable Interrupts
Timer1 = Timervorgabe
do
If Fensterschalter = 1 And Tuerkontakt = 1 And Eingangrauchmelder = 0 Then
Alarm = 1
Else
Alarm = 0
End If
If Eingangtaster = 1 Then
Dummy = 1
End If
loop

Timer_irq:
Timer1 = Timervorgabe
If Dummy = 1 And Eingangrauchmelder = 0 Then
Portb.1 = 1
Zaehler = Zaehler + 1
End If
If Zaehler = 25 Then 'auch dieser Wert ist nur zu Testzwecken'
Dummy = 0
Zaehler = 0
Portb.1 = 0
End If
Return

wenn ich nun die Variable Zaehler , Dummy und Timer1 beobachte stelle ich fest das sich nur Dummy auf 1 ändert Timer1 brav hochzählt aber die Variable Zaehler auf 0 stehen bleibt.
Dummy hat den Wert 1 und Eingangrauchmelder 0


Das Ganze ist recht Zeitunkritisch will sagen es kommt auf ne Minute nicht an grins' am Ende soll einfach ein Nachlauf von ca 30 Minuten rauskommen und dann Portb.1 abschalten.

Mir kommt es aber vor als ob er den Timer Interrupt garnicht macht bzw einfach überspringt... So wie ich das sehe müsste er ja zu
Timer_irq: springen und dort weiter werkeln...

Wo liegt denn nun der Hase im Pfeffer?

Jaecko
06.12.2010, 21:01
Zeig das Programm mal komplett (alles, auch Variablendeklarationen), dann können andere auch mal simulieren.

Rone
07.12.2010, 00:10
Hallo!

zum simulator:wenn Du eine Interruptroutine deklariert hast,
kann man nach anklicken des Reiters "Interrupts" dort den
jeweiligen Interrupt per Mausklick auslösen.

Aber wie immer der Hinweis auf die Bascom Hilfe. Ist dort beschrieben.

MfG
Rone

Edit: Wie schon Jaecko angemerkt hat, immer alles reinstellen.
Da fehlt die Timerinitialisierung, Variablendeklarationen,usw
So ist das Ganze recht sinnfrei!

Sauerbruch
07.12.2010, 08:01
Wo liegt denn nun der Hase im Pfeffer?

Meistens bei der Tatsache, dass Controller IMMER das machen was man ihnen sagt, aber nicht immer das was sie sollen :-)

Folgendes fällt auf den ersten Blick auf:

Der Timer läuft bei einem Wert von 65535 über. Wenn Du ihn in der ISR auf 65500 vorlädst, gibt es alle 35 Taktzyklen einen Timer1-Interrupt. Bei 1MHz wäre das alle 35µS, also knapp 30.000 Interrupts pro Sekunde. Ist das so gewollt? Wenn nicht, müsstest Du den Timer mit einem geeigneten Prescaler versehen (siehe Bascom-Hilfe...), und/oder den Preload-Wert verkleinern.

Die Geschichte mit "If Zaehler = 25 then..." geschieht natürlich auch nur ein einziges mal, denn in der nächsten ISR wird Zaehler um 1 erhöht, ist also nicht mehr 25. Je nachdem was Du damit erreichen möchtest (das erschließt sich mir im Moment leider nicht ganz), müsstest Du entweder Zaehler auf 0 setzen, wenn er den Wert von 25 erreicht hat (d.h. in der IF...EndIf-Schleife), oder aber mit > 25 abfragen.

Richard
07.12.2010, 08:15
Und bitte Programmzeilen in
xxxx
einfügen!

Gruß Richard

Halodri
07.12.2010, 16:55
Hallo zusammen!



Der Timer läuft bei einem Wert von 65535 über. Wenn Du ihn in der ISR auf 65500 vorlädst, gibt es alle 35 Taktzyklen einen Timer1-Interrupt. Bei 1MHz wäre das alle 35µS, also knapp 30.000 Interrupts pro Sekunde. Ist das so gewollt? Wenn nicht, müsstest Du den Timer mit einem geeigneten Prescaler versehen (siehe Bascom-Hilfe...), und/oder den Preload-Wert verkleinern.

Das macht natürlich sehr wenig Sinn und ist rein zu Testzwecken gedacht gewesen. Um mit F8 durchs Programm zu springen und um nicht von 49911
losklappern zu müssen habe ich den Timer als Vorgabewert auf diese 65500 gesetzt. Wie gesagt das ist NUR zum Testen mit F8 so gemacht.


Die Geschichte mit "If Zaehler = 25 then..." geschieht natürlich auch nur ein einziges mal, denn in der nächsten ISR wird Zaehler um 1 erhöht, ist also nicht mehr 25.

Auch dieser Wert 25 macht recht wenig Sinn der ist auch nur zu Testzwecken mit F8 so nieder gesetzt wenn ich den Fehler im System gefunden habe werden die 25 auf 1800 gesetzt das sollte dann so ca 30 Minuten entsprechen.

Diese bedein Werte 65500 beim Timer und 25 beim Zähler habe ich nur benutzt um mit der F8 Funktion durchs Programm zu steppen und um zu sehen ob sich dabei etwas ändert.

Aber mir schwant böses.. Kann es sein das selbst mit der Funktion F8 zu viele Interrupts ausgführt worden sind und somit bei jedem Sprung der Zähler gleich wieder auf 0 gesetzt wird? sodaß mir die Werte garnicht angezeigt werden?




$regfile = "m48def.dat"
$crystal = 1000000

Config Timer1 = Timer , Prescale = 64

Config Portb.1 = Output
Config Portd.0 = Output
Config Portd.1 = Output
Config Pind.2 = Input
Config Pind.3 = Input 'taster'
Config Pind.4 = Input
Config Pind.5 = Input
Config Pind.6 = Input
Config Portd.7 = Output
'Ports einrichten welcher Eingang und welcher Ausgang ist.'

Versorgungfensterschalter Alias Portd.0
Versorgungtuerkontakt Alias Portd.1
Alarm Alias Portb.1
Versorgungtaster Alias Portd.7
Fensterschalter Alias Pind.4
Tuerkontakt Alias Pind.5
Eingangrauchmelder Alias Pind.6
Eingangtaster Alias Pind.3


Dim Dummy As Bit
Dim Zaehler As Integer



Versorgungfensterschalter = 1
Versorgungtuerkontakt = 1
Alarm = 0
Versorgungtaster = 1



'Hier gehts beim Timer Interupt weiter'
On Timer1 Timer_irq

'um 1 Sekunde zu erreichen reichen die ticks von 49911 bis 65535'
Const Timervorgabe = 65500
'49911


'Hier werden die Timer aktiviert
Enable Timer1
Enable Interrupts
Dummy = 0
Timer1 = Timervorgabe

'Hier ist die Programmhauptschleife
Do

If Fensterschalter = 1 And Tuerkontakt = 1 And Eingangrauchmelder = 0 Then
Alarm = 1
Else
Alarm = 0
End If
If Eingangtaster = 1 Then
Dummy = 1
End If
Loop
End



Timer_irq:
Timer1 = Timervorgabe
If Dummy = 1 Then
Portb.1 = 1
Zaehler = Zaehler + 1
End If
If Zaehler = 25 Then
Dummy = 0
Zaehler = 0
Portb.1 = 0
End If

Return

Ihr habt natürlich Recht war Blödsinn von mir nur Schnipsel zu posten.

Ich hoffe ich hab mich nicht allzu schusselig angestellt But nobody is perfect.

Danke schon mal für Eure Geduld und Hilfe...

Grüße aus dem Süden

Rone
07.12.2010, 17:17
Hallo!

Mit F8 kannst Du keinen Interrupt auslösen!

Lies meinen Beitrag oberhalb und die Bascom Hilfe!

MfG
Rone

Netzman
07.12.2010, 18:13
35 Taktzyklen für eine ISR sind definitiv zu wenig, normalerweise werden dabei 32 Register gepusht und nachher gepopt + 6 Takte für Rücksprungadresse auf den Stack, Sprung ausführen, ...
Also nur damit eine leere ISR abgearbeitet wird vergehen schon mal doppelt soviele Takte wie überhaupt bis zum nächsten Interrupt zur Verfügung stehen.

mfg

for_ro
07.12.2010, 18:53
@Netzman Der Timer läuft mit Prescaler 64, also kommt die Timer ISR nur ca. alle 2000 Takte, also kein Problem.

@Rone Man kann auch mit F8 einen Interrupt auslösen, zumindest einen Timer Interrupt. Während er durch das Programm steppt, zählt der Timer hoch und bei Überlauf wird die ISR ausgeführt.

@Halodri F8 steppt durch die Bascom Befehle. Deren Abarbeitung kann natürlich ziemlich viele Takte Ausführungszeit benötigen. Locker über 1000. Ist aber in deinem Programm nichts drin, was mehr als 50 Takte dauert.
Wenn du das Ganze aber wirklich mit Prescale 1 ausführst, dann bekommst du in der Timer ISR tatsächlich ein Problem.
Timer1 = Timervorgabe
setzt den Timer auf Preload 65500. Jetzt kommen noch ein paar andere Befehle. Dann das Return. Der Rücksprung dauert 57 Takte. Während der ISR sind Interrupts global abgeschaltet, d.h. dass während dieser Takte nicht überprüft wird, ob der Timer überläuft. Wenn die Interrupts dann wieder eingeschaltet sind, ist der Timer schon übergelaufen und macht nun bei ganz niedrigen Werten (ca. 50) weiter.
Dies wird aber alles nicht passieren, wenn du mit Prescale 64 arbeitest.

Halodri
08.12.2010, 16:48
Hallo Leute!

Also irgendwie komme ich nicht weiter. ](*,)

Ich habe jetzt die Werte für Timervorgabe auf 49911 gesetzt dann sollte pro Sekunde ein ISR aufgerufen werden.

Aber dieser Zähler erhöht sich nicht. Ich bin mir fast sicher das die ISR garnicht aufgerufen wird. Da in der ersten Zeile ja steht
Timer1= Timervorgabe
Der Timer1 aber bei Überlauf wieder bei 0 anfängt zu zählen statt wie angegeben bei 49911...

Wie verhält sich das Prog denn bei Euch wenn Ihr es in Bascom einfügt und den Simulator startet. Zählt die Variable Zähler dann hoch oder nicht? Wo macht der Timer1 nach dem Überlauf weiter? Bei 0 oder bei 49911?


Danke für Euro Hilfe

Grüße aus dem Süden

Rone
08.12.2010, 18:42
Hallo!

Funktioniert hier bei mir.

Musst nur Deinen Eingangstaster auf 1 setzen, sonst wird Dummy nicht
gesetzt. Wenn Dummy nicht gesetzt wird, wird auch der Zähler nicht erhöht.

@for_ro:

Wieder was dazugelernt, aber ich probier auch nicht soviel mit dem Sim.
Übrigens: Das Programm funktioniert auch im Simulator ohne die
"$sim"-Anweisung. Dachte bisher die muss sein.

MfG
Rone

Jaecko
08.12.2010, 22:25
Nochwas zum lernen *g*:
Die $sim-Anweisung hat als einzigen Effekt, dass Warteschleifen rausgeworfen werden. So muss man z.B. bei einer LCD-Initialisierung nicht diese (im Simulator ewig dauernden) Delays abwarten muss. Da hier ja keine Hardware dranhängt, die sich beschweren könnte, können diese Delays in der Simulation also ausgeschlossen werden.

Nachtrag: Man kann auch ein mit $sim kompiliertes Programm auf den AVR werfen. Nur wird sich der halt u.U. seltsam verhalten.