Hallo,
ich steh hier im Moment auf dem Schlauch und bitte um Hilfe.
Im Lauf eines Programmes möchte ich zwei verschiedene Timer-Interrupts
freigeben. Aber nach der Freigabe des Zweiten ist der Erste wieder
gesperrt, zumindest funktioniert er nicht mehr. Ich habe folgendes
versucht:
sbr temp1, 1 << TOIE1 ; OVF-Interrupt Timer1 freigeben
out TIMSK, temp1
...
sbr temp1, 1 << OCIE2 ; COMPARE-Interrupt Timer2
out TIMSK, temp1
Funktioniert nicht, ich denke ich weiss auch warum und ich habe es dann
wie folgt versucht:
sbr temp1, 1 << TOIE1 ; OVF-Interrupt Timer1 freigeben
out TIMSK, temp1
...
in temp1, TIMSK
ori temp1, 1 << OCIE2 ; COMPARE-Interrupt Timer2
out TIMSK, temp1
Also mein Problem scheint zu sein: wie setze ich das Bit OCIE2 im
Register TIMSK und erhalte dabei das zuvor gesetzte Bit TOIE1?
Für Eure Hilfe wäre ich sehr dankbar!
das Problem hatte ich auch mal. Beim Schreiben nach TIMSK werden die
übrigen Bits auf 0 gesetzt. Also entweder nur einmal alle benötigten
Bits reinschreiben oder vorher auslesen, bit ändern und wieder
reinschreiben.
mfg
Du musst das I/O-Register schon vorher einlesen. Wenn Du in ein Register
mit "out" z.B. 0b00001000 reinschreibst, dann steht auch genau das
hinterher in diesem Register drin. Also mit "Read-Modify-Write" machen:
1
in r16, TIMSK
2
ori r16, (1 << TOIE1)
3
out TIMSK, r16
EDIT:
Sehe grad, dass Du genau das unten stehen hast. So sollte es auf jeden
Fall funktioneren. Damit wird jedenfalls TOIE1 gesetzt, und alle anderen
Bits bleiben so, wie sie vorher waren.
Thomas Otto wrote:
> ldi r16, (1<<TOIE0|1<<TOIE1)> out TIMSK, r16
Das wäre dann die Methode, mehrere Bits gleichzeitig zu setzen. Ich hab
das aber so verstanden, dass er sie nacheinander setzen will.
Es ist schon gelegentlich vorgekommen, dass man stundenlang an der
falschen Stelle sucht. Hast du per Debugging/Ausgabe kontrolliert, ob
das zweite Bit tatsächlich nicht gesetzt wird, oder vermisst du nur den
Interrupt?
@fragender
du kannst ja erst einen einschalten, dann ein bissel rumspielen, und
dann beide aktivieren. read modify write geht bei einigen registern
nicht. TIMSK koennte durchaus dadrunter sein. Vielleicht sagt das
Datenblatt ja was dazu.
cu Tarzanwiejane
Fragender wrote:
> temp1 = r16, keine Fehlermeldungen beim Assemblieren.
OK, wie ichs mir gedacht habe. Also: mehr Code. Das was oben steht,
müsste jedenfalls soweit funktionieren.
@fragender
haste mal geschaut ob deine interrupts einzeln ueberhaupt beide
funktionieren? dann kontrollier doch mal was im TIMSK drinsteht,
eventuell sind sie ja an aber deine Int-Routine ist Muell.
cu Tarzanwiejane
Thomas Otto wrote:
> @fragender> du kannst ja erst einen einschalten, dann ein bissel rumspielen, und> dann beide aktivieren. read modify write geht bei einigen registern> nicht.
Read-Modify-Write geht definitiv mit allen I/O-Registern und sogar mit
RAM-Speicherzellen! Wenn der obige Read-Modify-Write-Code nicht
fehlerfrei assemblieren sollte, dann muss man u.U. statt in und out lds
und sts benutzen, aber da es keine entsprechenden Fehlermeldungen
gegeben hat (Operand out of Range), geht das definitiv so.
Johannes M. wrote:
> Thomas Otto wrote:>> @fragender>> du kannst ja erst einen einschalten, dann ein bissel rumspielen, und>> dann beide aktivieren. read modify write geht bei einigen registern>> nicht.> Read-Modify-Write geht definitiv mit allen I/O-Registern und sogar mit> RAM-Speicherzellen! Wenn der obige Read-Modify-Write-Code nicht> fehlerfrei assemblieren sollte, dann muss man u.U. statt in und out lds> und sts benutzen, aber da es keine entsprechenden Fehlermeldungen> gegeben hat (Operand out of Range), geht das definitiv so.
Naja, stimmt schon, nur nicht immer. Es gibt einige Register die
loeschen gesetzte Bits nach dem reinschreiben. Da hilft dir dann das
Read-Modify-Nicht, auch wenn es denn strikt technisch gesehen
funktioniert.
cu Tarzanwiejane
Thomas Otto wrote:
> Naja, stimmt schon, nur nicht immer. Es gibt einige Register die> loeschen gesetzte Bits nach dem reinschreiben. Da hilft dir dann das> Read-Modify-Nicht, auch wenn es denn strikt technisch gesehen> funktioniert.
Du meinst Interrupt-Flags. Die stellen einen Sonderfall dar, was aber
nicht heißt, dass man auf die Interrupt-Flag-Register nicht mit
Read-Modify-Write zugreifen kann. Es ist eben nur unratsam. Da haben wir
möglicherweise ein wenig aneinander vorbeigeredet. TIMSK ist aber ein
"normales" I/O-Register, und deshalb ohne Probleme so wie oben
beschrieben behandelbar.
Johannes M. wrote:
> Thomas Otto wrote:>> Naja, stimmt schon, nur nicht immer. Es gibt einige Register die>> loeschen gesetzte Bits nach dem reinschreiben. Da hilft dir dann das>> Read-Modify-Nicht, auch wenn es denn strikt technisch gesehen>> funktioniert.> Du meinst Interrupt-Flags. Die stellen einen Sonderfall dar, was aber> nicht heißt, dass man auf die Interrupt-Flag-Register nicht mit> Read-Modify-Write zugreifen kann. Es ist eben nur unratsam. Da haben wir> möglicherweise ein wenig aneinander vorbeigeredet. TIMSK ist aber ein> "normales" I/O-Register, und deshalb ohne Probleme so wie oben> beschrieben behandelbar.
wenn der threadersteller sagen wuerde mit welcher der vielen AVR µC er
arbeitet, dann koennte man schauen ob dem tatsaechlich so ist... wer
weiss vielleicht gibts da ja den einen oder anderen Typen bei dem die
TOV-Flags mit im TIMSK sind. Beim Mega16 jedenfalls sollte
Read-Modify-Write auf dem TIMSK gut funktionieren.
cu Tarzanwiejane.