Forum: Mikrocontroller und Digitale Elektronik AVR: 2 Interrupts freigeben - klappt irgendwie nicht


von Fragender (Gast)


Lesenswert?

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!

von Fragender (Gast)


Lesenswert?

Deswegen ja der Versuch mit der Oder-Verknüpfung!

von Wolfram Q. (quehl)


Lesenswert?

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

von Andreas K. (a-k)


Lesenswert?

Wird wohl etwas mehr vom Programm rausrücken müssen.

von Johannes M. (johnny-m)


Lesenswert?

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.

von Thomas O. (tarzanwiejane)


Lesenswert?

ldi r16, (1<<TOIE0|1<<TOIE1)
out TIMSK, r16

cu Tarzanwiejane

von Johannes M. (johnny-m)


Lesenswert?

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.

von Fragender (Gast)


Lesenswert?

Ja, ich möchte es nacheinander im Verlauf des Programms machen.

Aber Read-Modify-Write scheint nicht zu funktionieren. Weiß nicht warum!

von Johannes M. (johnny-m)


Lesenswert?

Was ist temp1 bei Dir für ein Register? Gibts keine Fehlermeldungen beim 
Assemblieren?

von Andreas K. (a-k)


Lesenswert?

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?

von Fragender (Gast)


Lesenswert?

temp1 = r16, keine Fehlermeldungen beim Assemblieren.

von Johannes M. (johnny-m)


Lesenswert?

...und wie Andreas schon sagte: Schick mal was kompletteres.

von Thomas O. (tarzanwiejane)


Lesenswert?

@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

von Johannes M. (johnny-m)


Lesenswert?

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.

von Thomas O. (tarzanwiejane)


Lesenswert?

@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

von Johannes M. (johnny-m)


Lesenswert?

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.

von Thomas O. (tarzanwiejane)


Lesenswert?

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

von Johannes M. (johnny-m)


Lesenswert?

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.

von Thomas O. (tarzanwiejane)


Lesenswert?

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.

von Johannes M. (johnny-m)


Lesenswert?

@Thomas Otto:
Die Flags sind mit ziemlicher Sicherheit bei keinem AVR im 
Maskenregister drin.

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.