cbi TIFR, 1 -> out of range

Gast #348707
Lesenswert?
• ▲
▼
ich möchte im Timer Interrupt Flag Register mit dem Befehl "cbi TIFR"
ein Flag 0 setzen. Doch das löst nur die folgende Fehlermeldung aus:
warten2.asm(233): error: Operand 1 out of range: 0x38
Woran mag das liegen? Das TIFR ist doch auch ein I/O-Register, das mit
cbi, sbi anzusprechen sein müsste?!? (zumindest funktionieren die
Befehle "in" und "out" auf dem Register)
Gast #348711
Lesenswert?
• ▲
▼
das hat aber glaub ich eine (zwar sehr kleine) unzuverlässigkeit. wenn
ein flag nach dem IN befehl gesetzt wird, überschreib ich nachher mit
out diese flag, deswegen hätte ich gerne das ganze in einem befehl
gehabt
Gast #348714
Lesenswert?
• ▲
▼
> das hat aber glaub ich eine (zwar sehr kleine) unzuverlässigkeit.
> wenn ein flag nach dem IN befehl gesetzt wird, überschreib ich
> nachher mit out diese flag, deswegen hätte ich gerne das ganze in
> einem befehl gehabt

Wenn du den ausführst, nachdem das Flag gesetzt wurde, überschreibst
du's doch auch.
Gast #348715
Lesenswert?
• ▲
▼
Wenn Du in einem Register, das nur Interrupt-Flags enthält (TIFR,
GIFR...) ein Bit löschen willst (und das ginge sowieso nicht mit cbi,
selbst dann, wenn das Register im bitadressierbaren Bereich läge, da ein
Interrupt-Flag gelöscht wird, indem man eine eins hineinschreibt),
dann schreib einfach die Bitmaske, in der die zu löschenden Bits '1'
sind, mit out in das Register! Also wenn Du z.B. das OCF0 löschen
willst, dann einfach mit
ldi r16, (1 << OCF0)
out TIFR, r16
Da das Schreiben einer '0' sowieso keinen Effekt hat, funktioniert
das ganz hervorragend. Und in solchen Fällen: Finger weg von 'in ->
ori -> out'! Damit löschst Du alle Flags im Register, die zum
Zeitpunkt des Einlesens (in) gesetzt waren! Immer eine direkte
Zuweisung benutzen. Das gilt auch in C (also kein '|=' sondern ein
'=').

Im Datenblatt der AVRs steht übrigens auch noch, dass sbi und cbi
alle Bits im betreffenden Register betreffen! Wenn Du in einem
Register, das bitadressierbar ist und das gleichzeitig Interrupt-Flags
enthält (also z.B. ADCSR(A)) ein Bit mit sbi setzt, löschst Du
gleichzeitig alle Interrupt-Flags in diesem Register (also im Beispiel
das ADIF)!
Gast #348716
Lesenswert?
• ▲
▼
Ach, übrigens: Die Information über sbi und cbi steht in den
AVR-Datenblättern als Fußnote unter dem Register Summary. Ich hab das
damals auch eher zufällig entdeckt. Sonst habe ich diese Information
nirgends gefunden, auch nicht im Instruction Set Manual (wo sie imho
eigentlich hingehört)...

Die generellen Infos zum Löschen von Interrupt Flags gibts übrigens
auch in der AVR Checkliste auf dieser Seite.
Gast #348719
Lesenswert?
• ▲
▼
Das steht da nicht drin, weil es wirklich rein garnichts mit diesen
Befehlen zu tun hat. Das ist eine Eigenschaft des Registers und ist
völlig unabhängig davon, mit welchen Befehlen man das macht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren