PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Timer1 und Compare...



Murus
05.11.2005, 15:51
Hallo zusammen,
ich verwende einen Mega8, intern getaktet.
Dazu den Timer1 mit Prescale=8

Ich habe zwei Compare drinnen.
Compare1a und Compare1b.

So sieht der Timer1-spezifische Code in meinem Programm aus:
Config Timer1=Timer, Prescale=8
Enable Timer1
Enable Interrupts
On Compare1a Interrupteins
On Compare1b Inzerruptzwei
D=85
Y=1250
Compare1a=D
Compare1b=Y

Interrupteins:
D=D+85
Compare1a=D
.
.
.
Return
Interruptzwei:
Y=Y+1250
Compare1b=Y
.
.
.
Return

In den jeweiligen Interrupt-Routinen werden die entsprechenden Werte zum Wert des Compare-Registers dazuaddiert, damit nach der richtigen Zeit der Interrupt wieder kommt...

Nur: Der Code funktioniert irgendwie nicht...
Hab ich was vergessen? In meinen Augen sollt er gehen..
Herzlichen Gruss
Mario

06.11.2005, 21:14
du solltest mal den interrupt disablen wenn du die comparewerte änderst.
mfg psft

Murus
07.11.2005, 19:33
Ok, Interrupts hab ich disabled, geht trotzdem nicht!
Ich hab mal schnell ein Testprogramm geschrieben, mit dem ich mit dem Bascom-Simulator das Ganze testen will:



Config Timer1 = Timer , Prescale = 8 ' Timer 1 für Zeit und Array
Enable Timer1
Enable Interrupts


On Compare1a Eins
On Compare1b Zwei

Dim X As Long
Dim Y As Long
X = 1
Y = 6
Compare1a = X
Compare1b = Y
Start Timer1
Cls
Locate 2 , 1
Lcd "Hello World"
Do
Loop

Eins:

X = X + 5
Compare1a = X
Cls
Locate 1 , 1
Lcd "Eins"


Return

Zwei:

Y = Y + 5
Compare1b = Y
Cls
Locate 1 , 1
Lcd "Zwei"

Return

End
Aber:
Auch das funktioniert nicht! Deshalb meine Frage: Kann das Bascom überhaupt? In der Hilfe und den Samples steht nirgends etwas, bei dem der Timer1 in dieser Funktion verwendet wird....

Herzlichen Gruss
Mario

07.11.2005, 20:07
....Der Wert im Output Compare Register wird ständig mit dem aktuellen Wert im Datenregister TCNT1H/TCNT1L verglichen. Stimmen die beiden Werte überein, so wird ein sogenannter Output Compare Match ausgelöst. Die entsprechenden Aktionen werden über die Timer/Counter 1 Control und Status Register eingestellt.

Zum Auslesen des Registers wird von der CPU ein internes TEMP-Register verwendet. Das gleiche Register wird auch verwendet, wenn auf OCR1 oder ICR1 zugegriffen wird. Deshalb müssen vor dem Zugriff auf eines dieser Register alle Interrupts gesperrt werden, weil sonst die Möglichkeit des gleichzeitigen Zugriffs auf das Temporärregister gegeben ist, was natürlich zu fehlerhaftem Verhalten des Programms führt.. Zudem muss zuerst OCR1L und erst danach OCR1H ausgelesen werden.

Wenn in das Register geschrieben werden soll, müssen ebenfalls alle Interrupts gesperrt werden. Dann muss zuerst das OCR1H-Register und erst danach das OCR1L-Register geschrieben werden, also genau die umgekehrte Reihenfolge wie beim Lesen des Registers.....

ein interessanter auszug.
mfg psft

Murus
07.11.2005, 20:18
Ok, also wenn der Interrupt kommt
"disable Interrupts" schreiben, und dann vor "return" wieder enablen...

Nur: Wie geht das mit dem OCR1? (Bascom-Befehl) Muss ich die im Dualsystem beschreiben? Wie läuft das jetzt? Welches Byte zuerst?
Ich muss zuerst eine Zahl ins OCR1H stecken und dann eine Zahl ins OCR1L. Nur: Wie? Wenn ich z.B. 100 da reintun möchte.. ?

Herzliche Grüsse und Danke für deine Unterstützung!
(Was meinst du mit interessanter Auszug? Ist doch ein etwas falscher Code.. ?)

hrei
07.11.2005, 22:33
Ok, also wenn der Interrupt kommt
"disable Interrupts" schreiben, und dann vor "return" wieder enablen...

Genau.


Nur: Wie geht das mit dem OCR1? (Bascom-Befehl) Muss ich die im Dualsystem beschreiben? Wie läuft das jetzt? Welches Byte zuerst?
Ich muss zuerst eine Zahl ins OCR1H stecken und dann eine Zahl ins OCR1L. Nur: Wie? Wenn ich z.B. 100 da reintun möchte.. ?


Ganz einfach. Bascom erledigt das sortieren der Reihenfolge selbst, Du brauchst Dich also nicht darum zu kümmern.

COMPARE1A = var
var = COMPARE1A TIMER1 COMPARE A register
COMARE1B = var
var = COMPARE1B TIMER1 COMPARE B register

So steht es auch in der Hilfe.

Pebisoft macht die Dinge eben gerne etwas komplizierter, als sie sind.

Grüße
Henrik

07.11.2005, 22:39
wenn bascom dein "disable interrupt" nicht annehmen/verarbeiten tut,
kannst du die register nicht beschreiben.
mfg psft

hrei
07.11.2005, 23:06
wenn bascom dein "disable interrupt" nicht annehmen/verarbeiten tut,
kannst du die register nicht beschreiben.


Warum sollte Bascom "disable interrupts" nicht ausführen? Das tut es bei mir -und nicht nur bei mir- völlig problemlos. Wäre schön, wenn Du Dich an Deine Schreibsperre halten würdest.

Henrik

08.11.2005, 08:38
der gast ist pebisoft und nicht anonymous . hast wohl probleme oder.


--------------------DELETED ------------------ (PicNick)

08.11.2005, 08:42
dann kann ich dir das proggen und die interna von bascom mal beibringen.
mfg psft

08.11.2005, 13:36
Heyhey, der Typ wollt mir doch nur helfen!

Also, ich probiers mal
Unter welchem Aspekt in der Hilfe haste das gefunden? Was bedeutet das register in deinem code?

Murus
09.11.2005, 20:40
Also, ich hab jetzt mal noch an dem Zeug rumgeprügelt und habs nicht hingekriegt... In der Bascom Hilfe finde ich die Compare-Funktion nur in Interaktion mit Pins, und das will ich ja net....

Hilfeeee.. Ich versteh auch den obigen Codeschnipsel net... Der Simulator scheint mir da auch etwas "komisch" zu sein, ich baus mal mit zwei Leds real auf, aber ich brauch den Code...

Herzliche Grüsse
Mario

Marco78
09.11.2005, 21:07
Das Register läuft ja irgendwann über wenn du immer nur addierst.
Vielleicht fehlt ein IF Wert is zu groß, dann Wert = 0 ???

Funktioniert nicht ist ja nicht sehr aussagekräftig.

Murus
09.11.2005, 21:13
Das mit dem Überlaufen regelt Bascom selber. Er schmeisst den "Rest" weg und beginnt mit dem vorigen Wert wieder von 0.
Aber das ist ja nicht das Problem, er bringt mir (im Sim) ja nicht mal den ersten Interrupt, bei dem er mir aufm LCD etwas anzeigen soll.
Ich hab einfach den Code nicht.
Wie muss ich jetzt Timer1 initialisieren?
Wie schreibe ich die Doppelregiser (unter Bascom)
Was gibt es sonst noch zu beachten?

Herzlichen Gruss
Mario

Murus
12.11.2005, 12:53
Also, ich hab jetzt mal ein Testprogramm gebaut. Eine Led soll über den Compare-Interrupt blinken.
Hier ist mal der Code:

$regfile = "m8def.dat"
$crystal = 1000000
Ddrd.7 = 1
Portd.7 = 0
Config Timer1 = Timer , Prescale = 8
Enable Interrupts
On Compare1a An

Dim X As Long

X = 1500

Compare1a = X

Enable Timer1
Do
Loop

An:
Disable Interrupts
X = X + 1500
Compare1a = X

Toggle Portd.7
Enable Interrupts
Return

End

Doch: die Led bleibt dunkel!
Was ist falsch?
Könnt ihr mir da weiterhelfen?

Herzlichen Gruss
Mario

Marco78
12.11.2005, 17:29
Was hast du eigentlich vor? PWM? Comapre=vergleichen. Was wird denn verglichen?


Das mit dem Überlaufen regelt Bascom selber.
Geht ja garnicht. Wenn das Programm im AVR ist hat BASCOM damit ja nichts mehr zu tun.

Murus
12.11.2005, 17:34
Jo, der AVR regelt den Überschuss.
Ich vergleiche den Wert im OCR1a-Register mti dem aktuellen Zählerstand von Timer1. Ist er gleich, soll ein Interrupt kommen und der Stand im OCR1a neu gesetzt werden.
Nur geht das nicht, da ich die Befehle nicht kenne.