Forum: Mikrocontroller und Digitale Elektronik TOV0 in TIFR setzen...wie ?


von Tilman (Gast)


Lesenswert?

Schönen guten Tach,
ich will das Timer/Counter0 Overflow Flag TOV0 im Register TIFR setzen
(ATTiny 2313 mit AVR Studio). Wie geht das ? SBI TIFR,1 klappt nicht,
Compiler meckert: "Operand 1 out of range" .
Danke für jeden Ratschlag.
Tilman

von Rolf Magnus (Gast)


Lesenswert?

> ich will das Timer/Counter0 Overflow Flag TOV0 im Register TIFR
> setzen (ATTiny 2313 mit AVR Studio). Wie geht das ?

Gar nicht. Man kann es nur löschen. Das tut man allerdings
verwirrenderweise, indem  man eine 1 reinschreibt.

> SBI TIFR,1 klappt nicht, Compiler meckert: "Operand 1 out of
> range" .

Da hat er recht :)
TIFR ist ein Register, das sich nicht mit sbi ansprechen lässt. Also
so:

in r16, TIFR
ori r16, (1 << TOV0)
out TIFR, r16

von mmerten (Gast)


Lesenswert?

Bitte mal die Suche bemühen. Beim TINY2313 liegen viele Peripherie
Register außerhalb des mit SBI/CBI adressierbaren Bereiches.
Auch kann ein Interrupt-Flag nicht manuell gesetzt werden. Nur das
Zurücksetzen indem eine "1" zurückgeschrieben wird ist möglich.

von Netbandit (Gast)


Lesenswert?

Ja ich bin ja vor 2 Wochen auch in die AVR programmierung
eingestiegen... und das man mit ldi nicht r0 bis r31 sondern nur r16
bis r31 ansprechen kann ist genauso unlogisch wie die sache mit
verscheiden Registern welche sich per sbi und cbi nicht ansprechen
lassen.

Hat jemand eine Ahnung warum das so ist? Oder ist das einfach nur eine
dumme eigenheit der AVRs.

Ich meine man, kommt zwar auch so zum Ziel, aber oft benötigt man dann
ein weiteren Befehl (mehr Zeit) oder ein zusätzliches Register welches
man im Notfall sogar noch mit push und pop vorher retten muß (noch mehr
Zeit, mehr Stackverbrauch)

von Tilman (Gast)


Lesenswert?

Heey, Danke für Eure Antworten. Das funktioniert wunderbar, Rolf.
Entschuldigt bitte meine Unwissenheit. Learning by asking.
Gruß, Tilman.

von Tilman (Gast)


Lesenswert?

Ich weiss auch nicht, weshalb man die meisten Befehle nur bis
einschliesslich r31 verwenden kann, Bandit. Frag die Experten (Rolf,
MMerten). Ich bin hier leider nicht tief genug in der Materie.

von Jörn G. aus H. (Gast)


Lesenswert?

Weil alle Befehle nur 2 Byte lang sind.
Im Gegensatz zu anderen Controllern ist das unglaublich komprimierter
Opcode, da es ja sehr viele komfortable Befehle gibt (im Gegensatz
wiederum zum PIC, wo User mit sehr wenigen Befehlen in Assembler
auskommen muß).

Wenn du dir die ganzen Opcodes ansiehst (also die Hex-Zahlen, die den
Assembler Vebfehlen entsprechen), dann siehst, du, dass bei manchem
Befehlen quasi der Befehlsname lang ist, dann bleiben von den 16bit
evtl. nur noch 5 Bit für den Paramter übrig, also nur für die ersten 32
Register.

Andere Befehle haben sehr kurze "Namen", dann bleibt mehr Platz für
die Parameter.

Es kann aber eben nicht beliebig viele Kurz-namige Befehle geben, weil
es dann zu wenige am Ende wären.

Das ganze ist sehr durchdacht und keine schlichte Nebenwirkung
irgendwelcher "Modernisierungsmaßnahmen", wie bei vielen aufgebohrten
alten Controller-Kernen.

jörn

von Netbandit (Gast)


Lesenswert?

Ja stimmt, das ergibt dann auch einen Sinn :)
Ich habe mich bis jetzt nur einfach totgeärgert wenn mal wieder so ein
Fall dran war.
Doch hätte ich dann wohl noch einen äquivalenten Befehl für die
restlichen Register eingebracht. Aber gut das überlasse ich mal den
Profis von Atmel :)

Aber du hast recht, ich habe vorher nur mit PIC16Fxxx gearbeitet und da
war mir der Befehlssatz etwas zu dürftig... beim PIC18 soll es ja etwas
besser sein. Aber der AVR lässt sich schon schöner programmieren.

von Läubi (Gast)


Lesenswert?

Naja man nimmt einfach die ersten Regsiter für alle Sachen die nicht soo
ft oder sogar garnicht mit Imideate werden benötigt werden.
Ansosnten halt ein Temp Register + ein Mov befehl.

von Netbandit (Gast)


Lesenswert?

ja so mache ich es ja auch... ich hatte mich einfach in der Vergagenheit
immer gewundert warum das so ist. Nun weiß ich es ja :)

von Rolf Magnus (Gast)


Lesenswert?

Mal ein Beispiel:

ldi ist 16 bit breit. 8 Bit davon werden schon mal für den zu ladenden
Wert benötigt. Bei 32 Registern würde man für die Registernummer
nochmals 5 Bit brauchen. Dann wären für den eigentlichen Befehl selbst
nur noch 3 Bit übrig. Damit würde ldi aus dem gesamten "Befehlsraum"
(16 bit = 65536 verschiedene mögliche Werte) alleine ein Achtel
belegen. Und es gibt ja noch einige weitere Befehle mit Immediate (adi,
subi, sbci, cpi, ori, andi). Da sieht man schon, daß das ziemlich eng
würde. Deshalb hat man hier bei der Registernummer ein Bit gespart, was
aber eben dazu führt, daß nur die Hälfte der Register mit diesen
Befehlen angesprochen werden kann.

von Hannes L. (hannes)


Lesenswert?

Ist aber immer noch bedeutend flexibler als eine Architektur mit Akku,
R-Register und Y-Register...

;-)

...

von crazy horse (Gast)


Lesenswert?

es gab ganz am Anfang der AVRs (da gabs nur 1200, 2313 und 8515) die
Idee , eine Art Bankselect-bit einzuführen, da sollte R0 mit R16 usw.
getauscht werden, ein ldi r16, xx würde dann ein ldi r0,xx bedeuten.
Meiner Meinung nach zum Glück nie wirklich realisiert. Ich kann mit der
kleinen Einschränkung gut leben. Und wenn man in einer Hochsprache
programmiert, merkt man davon sowieso nichts.

von Hannes L. (hannes)


Lesenswert?

Ich habe damit auch keine Probleme (meht). Wenn man erstmal verstanden
hat, dass der Adressbereich

- 16 "dumme" Register (kein immidiate)
- 16 "bessere" Register (incl. Doppelregister/Pointer)
- 32 "hochwertige" (und "schnelle") I/Os (Bit-Zugriff möglich)
- 32 "schnelle" I/Os (Byte-Zugriff mit IN/OUT)
- bis zu 160 "blöde" I/Os (Extendet-I/O im SRAM-Bereich)
- internes SRAM
- externes SRAM via Speicherinterface (noch nie benutzt)


hat, dann sollte man damit auch klarkommen.

Man muss sich eben mal mit der Architektur des AVRs vertraut machen,
die aber doch recht überschaubar ist.

...

von hans dieter (Gast)


Lesenswert?

um jetzt noch mal auf das eigentliche problem zurück zu kommen:
setze den zähler-wert auf den wert vor dem überlauf wert und dann lasse
den zähler überlaufen.
(Je nach dem welchen Modus du verwendest geht das oder auch nicht)
oder, wenn es nur auf die auslösung des interrupts auskommt, dann rufe
ihn einfach auf.

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.