Forum: Mikrocontroller und Digitale Elektronik Timer1: Compare-mode spinnt


von Mario Mauerer (Gast)


Lesenswert?

Guten Abend zusammen,

ich versuche gerade, Timer1 dazu zu bewegen, mir bei seinem Durchlauf 2
Interrupts auszulösen. Kurz: Ich krieg das Compare-Zeugs nicht gebacken.
Ich programmiere mit Bascom.
Kann jemand schnell die passenden Codeschnipsel posten?
Wie initialisiere ich den Timer?
Wie schreibe ich die Vergleichs-Register in der Interrupt-Routine?

In der Bascom Hilfe kommt der Compare-Mode nur in Zusammenhang mit Pins
(an-abschalten) vor, ich brauch aber Interrupts....

Kann mir ein Bascom-Wissender helfen?

Herzliche Grüsse
Mario

von Ralf (Gast)


Lesenswert?

Wie wärs, wenn du mal angibst, welchen Controller du verwendest?
Ausserdem wärs nicht schlecht, wenn du deinen Code postest, dann würden
wir vielleicht gleich sehen, wo der Fehler liegt. Und es ist auch nicht
schlecht, wenn du sagst, warum du das so brauchst. Könnte ja sein, dass
man es einfacher bzw. ohne Timer oder was weiss ich lösen kann.

Schließlich können wir nicht hellsehen... Ist nicht bös gemeint, aber
ich glaube, wenn du so drüber nachdenkst, kommst du auch zu dem
Schluss, dass das besser wäre, hm?

Ralf

von Mario Mauerer (Gast)


Lesenswert?

Kann bestätigen, ich komm zu dem Schluss! :)

Also:
Ich verwende den Mega8 und Bascom
Ich brauch halt einfach den Timer1 mit zwei Interrupten, ich möchte das
auch aus lerntechnischen Gründen nicht mit zwei Timern lösen.

Hier mal mein Code bisher:
(ist nur ein "Testprogramm" für diese Timer-Funktion)
Das LCD wird vorher korrekt initialisiert, hier nur die Timer-Sequenz
des Codes.

Config Timer1 = Timer , Prescale = 8
Enable Timer1
Enable Interrupts

On Compare1a Eins
On Compare1b Zwei

Dim X As Long
Dim Y As Long
X = 10
Y = 16
Compare1a = X
Compare1b = Y
Start Timer1

Cls

Locate 2 , 1
Lcd "LCD-Runs!"

Do
Loop

Eins:
disable Interrupts
X = X + 10
Compare1a = X
Cls
Locate 1 , 1
Lcd "Eins"

Enable Interrupts
Return

Zwei:
disable Interrupts
Y = Y + 5
Compare1b = Y
 Cls
Locate 1 , 1
Lcd "Zwei"
Enable Interrupts
Return

End

Doch: die Interrupts werden nicht ausgelöst! Es kommt keiner. Das LCD
funktioniert, es liegt am Timer.

Ich entschuldige mich für die knappe Ausdrucksweise, ich war in Eile.

Herzlichen Gruss
Mario

von Ralf (Gast)


Lesenswert?

Autsch, mit AVR's kenn ich mich nun gar nicht aus, ich bin auf 8052er
getrimmt ;-)

Musst ein bisschen warten, da schaltet sich bestimmt noch jemand dazu,
der sich mit AVR's auskennt...

Gruß Ralf

von Hannes L. (hannes)


Lesenswert?

Was erwartest du eigentlich vom Timer?

Ein Compare-match-Interrupt tritt auf, wenn der Zählerstand von
tcnt1(h:l) den Stand von ocr1a(h:l) bzw. ocr1b(h:l) erreicht.
Du addierst jeweils 5 oder 10 zu den OCR1xx-Registern. Das sind bei
Vorteiler 8 40 bzw. 80 Prozessortakte.

Dann schreibst du noch in der ISR Text auf das LCD.
- Wieviele Takte braucht diese Textausgabe eigentlich?
- Wieviel Zeit hast du überhaupt in der ISR, wenn du nach 40 bzw. 80
Takten schon den nächsten Interrupt erwartest? Dabei kostet der Aufruf
eines Interrupts und der Rücksprung alleine schon 10 Takte in ASM, ich
glaube kaum, dass BASCOM das schneller kann.

Vielleicht solltest du BASCOM erstmal (nur vorübergehend) beiseite
legen und die Hardware-Features des Controllers mittels Datenblatt und
Assembler (AVR-Studio) kennen lernen. Dann bekommst du vielleicht ein
Gefühl für das Machbare...

...

von Peter Dannegger (Gast)


Lesenswert?

Da hat HanneS völlig recht.

In Interrupts so schnarchlahme Sachen zu machen, wie LCD-Ausgaben ist
ganz ganz schlecht.


Auch solltest Du daran denken, daß ein Text mindestens 500ms stehen
bleiben sollte, damit Du ihn auch ablesen kannst.


D.h. die Interrupts kommen schon, aber viel langsamer als Du willst und
das Display kann keinen der Texte anzeigen, da Du ihn ja sofort wieder
löschst.


Peter

von Mario Mauerer (Gast)


Lesenswert?

Oh, ich vergass zu erwähnen, dass ich das Programm bis jetzt nur im
Bascom-Simulator laufen liess, und der taktet ja nicht mit einem
Megahertz...
Daher die struben Werte, mit höheren Zahlen gings auch net....

Mich interessiert, ob der Code so korrekt ist... Dann werd ichs nämlich
mal mit Leds testen, aber wenns der Sim net frisst, wirds in Realität
wohl auch net anders gehen, oder doch?

Herzlichen Gruss
Mario

von Mario Mauerer (Gast)


Lesenswert?

Hmm, ich bau jetzt einfach mal das Ding mit Leds nach. Ich hab die
Comparewerte zu klein gewählt (auch für den Sim). Stimmt der obige
Code?

von Mario Mauerer (Gast)


Lesenswert?

Also, ich hab das Programm jetzt mal gebaut.
Ich möchte mit einem Compare-Interrupt eine Led an- und ausschalten.
Hier ist 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 ausgeschaltet!

Warum? Könnt ihr mir helfen, dieses Compare-Zeug zum laufen zu bringen?
Ich komm sonst net weiter... Es hat doch sicher jemand das schon mal so
gemacht....

von Peter D. (peda)


Lesenswert?

Ich kenne mich in Basic nicht aus und ohne Kenntnis der
Basic-Spezialfunktionen kann man da nichts erkennen.

Was merkwürdig aussieht:

"On Compare1a An"

definiert wohl einen Interrupthandler (wird damit auch der Interrupt
enabled ?).

Aber:

"Compare1a = X"

weißt dem Interrupthandler einem Wert zu ???

Man sollte schon für Variablen und Funktionen unterschiedliche Namen
nehmen (unter C ginge sowas erst garnicht).


Wenn man Basic-Spezialfunktionen nimmt, muß man auch genau das Manual
dazu durchlesen bzw. es gibt bestimmt auch Beispiele dazu.

Unter C nimmt man keine Spezialfunktionen sondern man setzt alle
IO-Register selber, wie es laut Datenblatt zu erfolgen hat.
Damit hat man keinen Trouble, daß ein anderer es nicht verstehen kann
oder irgendwas anders erfolgt, als man vermutet.


Peter

von Mario Mauerer (Gast)


Lesenswert?

In der Hilfe zum Compiler steht dazu eben nichts!!
Darum frage ich hier ja an!

von Hannes L. (hannes)


Lesenswert?

@Mario...

Es ist ganz einfach:

In die dementsprechenden I/O-Register müssen die dementsprechenden
Werte gesetzt werden (einzelne Bits setzen).
Diese I/O-Register und deren Bits haben eindeutige Namen, die man im
Datenblatt nachlesen kann. Diese Namen sind verbindlich, egal ob man
(wie ich) in Assembler "rumgurkt" oder (wie Peter) in C
programmiert.

Eine Hochsprache, die ihre eigenen Namen verwendet, ist untauglich!
Daher verwendet hier auch kaum jemand dieses BASCOM.

Ich habe gewiss nix gegen BASIC als Hochsprache, ich benutze es z.B.
auf dem PC und auf dem Commodore Plus/4, aber das BASCOM für AVRs ist
eher eine Bremse als eine Hilfe. Es suggeriert zwar aufgrund der
mitgelieferten Bibliotheken schnellen Erfolg, aber sobald es ins Detail
geht, wird man verdummt. Sorry, das ist mir irgendwo zuviel BASIC, zu
weit weg von der Hardware, deshalb verzichte ich freiwillig darauf...

...

von Peter D. (peda)


Lesenswert?

"In der Hilfe zum Compiler steht dazu eben nichts!!"

Wirklich nicht ?
Hast Du denn überhaupt im Bascom-Verzeichnis gesucht ?
Und auch keine Beispiele gefunden ?

Dann ist Bascom aber große Scheiße.


Vielleicht Datenblatt lesen und selber machen, also:

TCCR1A =
TCCR1B =
TIMSK =
OCR1A =
usw.

Bascom versteht doch wenigstens die IO-Registernamen, die Atmel
vordefiniert hat ?


Peter

von Mario Mauerer (Gast)


Lesenswert?

Jo, ich hab schon probiert die Werte ins OCR1a- Register zu schmeissen,
hat er nicht gefressen, obwohl man auch ASM programmieren kann (mit
Bascom, er versteht es). (Also: OCR1A=X, das frisst er net)

Die anderen Register für den Timer (TIMSK, TCCR1A etc. ) gehen gut mit
der Hochsprache, das ist das "config Timer1" etc....


??

von Mario Mauerer (Gast)


Lesenswert?

Oh, falls das mit dem Compare-Zeugs jemand in ASM da hat, kann er mir
den Codeschnipsel schicken? Dann würde ich direkt den Assemlber-Code
einbinden...

Herzlichen Gruss
Mario

von Hannes L. (hannes)


Angehängte Dateien:

Lesenswert?

Willst du dir das wirklich antun???

Dann viel Spaß...

...

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.