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
> 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
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.
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)
Heey, Danke für Eure Antworten. Das funktioniert wunderbar, Rolf. Entschuldigt bitte meine Unwissenheit. Learning by asking. Gruß, Tilman.
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.
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
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.
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.
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 :)
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.
Ist aber immer noch bedeutend flexibler als eine Architektur mit Akku, R-Register und Y-Register... ;-) ...
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.
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. ...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.