Forum: Mikrocontroller und Digitale Elektronik Löschen eines Bits löscht auch ein ganz anderes Bit. Weshalb?


von Schmidt (Gast)


Lesenswert?

Hallo ihr Lieben,

beim Versuch den Timer1 des ATMega8515 zu benutzen ist mir Dank des 
AVRStudio Simulators folgendes aufgefallen:
1
...
2
(1) TIMSK |= (1<<TOIE1); //Interrupt bei Überlauf Timer/Counter1 erlauben
3
(2) TIMSK &= (1<<OCIE1A); //Kein Interrupt bei Vergleichswert A (Timer/Counter1)
4
...

Befehl (1) wurde korrekt ausgeführt.
Befehl (2) löschte auch das vorher gesetzte Bit TOIE1.

Somit funktioniert mein Mikrocontroller natürlicht nicht mehr wie er 
soll.

Ich habe im Datenblatt eine Erklärung gesucht, sie jedoch nicht 
gefunden. Dabei habe ich allerdings nicht jede der 251 Seiten gründlich 
durchgelesen.



Kann mir jemand dieses Verhalten erklären?


Ich habe Befehl (2) einfach auskommentiert, da nach einem Reset sowieso 
alle Werte auf 0 gesetzt sind. Schreibt man nur einsen, dann geht alles 
glatt. So funktioniert es.

Was jedoch, wenn ich nun nach einiger Zeit meinen Timer1 umstellen und 
anders nutzen möchte?


Es scheint nun also nicht zu funktionieren die entsprechend zu ändernden 
Bits auf 1 oder 0 zu setzen.
Aber kann ich mir andersherum sicher sein, dass bei einem setzen eines 
Bits auf 0 alle Bits gelöscht werden? Kann ich mich darauf verlassen und 
danach nur noch die einsen schreiben?

Um sicher zu gehen, dass alles wie gedacht gesetzt wird müsste ich 
zuerst alle nullenden Befehle aufrufen und dann erst all jene, die auf 1 
setzen.

Das führt zu einem Recht unübersichtlichem Kuddelmuddel das ich gerne 
vermeiden wollen würde.
Oben wird ein Teil der Clockselect Bits auf Null gesetzt, dann kommt 
etwas ganz anderes was auf null gesetzt wird, und noch viel viel weiter 
unten wird dann ein anderer Teil der Clockselect Bits auf eins gesetzt.
Ein unangenehmes Durcheinander würde das.


Ich hoffe auf fachkundige und erleuchtende Erklärungen.

Vielen Dank
Schmidt

von holger (Gast)


Lesenswert?

>(1) TIMSK |= (1<<TOIE1); //Interrupt bei Überlauf Timer/Counter1 erlauben
>(2) TIMSK &= (1<<OCIE1A); //Kein Interrupt bei Vergleichswert A

(2) TIMSK &= ~(1<<OCIE1A); //Kein Interrupt bei Vergleichswert A

von Chris L. (kingkernel)


Lesenswert?

Versuchs mal damit:
1
TIMSK &= ~(1 << OCIE1A);

von Testuser (Gast)


Lesenswert?

1
TIMSK &= ~(1<<OCIE1A)

von Chris L. (kingkernel)


Lesenswert?

Bei
1
 TIMSK &= (1<<OCIE1A);
löschst du alle Bits bis auf das in OCIE1A. Mit ~ kehrst du das Byte 
bitweise um und behälst alle, bis auf dieses

von Schmidt (Gast)


Lesenswert?

Ach schade...

..schade, dass es wieder mal ein öder "Ein-Zeichen-Fehler" war.

Ich dachte es würde viel spannender werden und tiefer in die Materie 
gehen.

Vielen Dank für eure Antworten.

Gruß
Schmidt

von holger (Gast)


Lesenswert?

>Ich dachte es würde viel spannender werden und tiefer in die Materie
>gehen.

Wenn du was spannendes willst:

In der Mainloop

if(wert1 == 0) PORTB |= 0x03;
else PORTB &= ~0x03;

In einem Interrupt:

if(wert2 == 0) PORTB |= 0x0C;
else PORTB &= ~0x0C;

Viel Spaß beim nachdenken;)

von Schmidt (Gast)


Lesenswert?

holger schrieb:
> Wenn du was spannendes willst:
>
> In der Mainloop
>
> if(wert1 == 0) PORTB |= 0x03;
> else PORTB &= ~0x03;
>
> In einem Interrupt:
>
> if(wert2 == 0) PORTB |= 0x0C;
> else PORTB &= ~0x0C;
>
> Viel Spaß beim nachdenken;)

Worin besteht das Rätsel?

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.