Gibt es etwas wie "(0 << BIT7)"?

Gast #3708655
Lesenswert?
• ▲
▼
Hallo,

man kann im AVR Studio ja ein Bit mit Einsern in der Form (1 << 
Position) laden. Gibt es das auch umgekehrt?

Bzw gibt es eine bessere möglichkeit ein Port einzulesen und ein 
bestimmtes, aber per Variable definiertes Bit, auf Null zu setzen? Mit
IN temp, PORTX
ANDI temp, 0b11101111
OUT ...
geht es zwar, aber die Position der Null ist festgelegt und nicht per 
(Präprozessor-)Variable definierbar.


Danke für Hilfe
#3708662
Lesenswert?
• ▲
▼
Neuling schrieb:

> IN temp, PORTX
> ANDI temp, 0b11101111
> OUT ...
> geht es zwar, aber die Position der Null ist festgelegt und nicht per
> (Präprozessor-)Variable definierbar.

ABer 0b11101111 ist ja nichts anderes als die binäre Umkehrung (aus 0 
mach 1, aus 1 mach 0) von 0b00010000. Und das wiederrum ist ja nichts 
anders als (1<<PD4).

D.h. du brauchst die Operation die im Präprozessor einfach diese 
Umkehrung macht. Das wiederrum macht das Symbol '~'.

Aber. Wenn du sowieso in Assembler nur 1 BIt an einem Port setzen bzw. 
löschen willst, warum benutzt du dann nicht ganz einfach die 
Spezialbefehle, die Atmel ihren AVR Prozessoren spendiert hat?

Siehe AVR-Tutorial

(0<<PD4) ist soweit keine sinnvolle Operation. Denn was macht denn das 
<< ?
Das ist eine Schiebeoperation.
Bei (1<<PD4) wäre das sinnvoll. PD4 ist ja nichts anderes als eine 
andere Schreibweise für 4. D.h. da steht
1
    1 << 4
und das bedeutet einfach nur, dass eine binäre 1
1
   0000 0001
um 4 BIts nach links geschoben wird
1
  0000 0001     Original
2
  0000 0010     1 mal verschoben
3
  0000 0100     2 mal verschoben
4
  0000 1000     3 mal verschoben
5
  0001 0000     4 mal verschoben
d.h. das 1 Bit im Original wandert sukzessive nach links.

Jetzt mach das mal mit 0 << PD4
1
  0000 0000     Original
2
  0000 0000     1 mal verschoben
3
  0000 0000     2 mal verschoben
4
  0000 0000     3 mal verschoben
5
  0000 0000     4 mal verschoben
da entsteht genau dasselbe wie im Original. Einen Wert von 0 nach links 
zu verschieben ist daher eine sonnlose Operation, weil sich nichts 
ändert. Das Ergebnis ist genauso einfach 0, wie es das Original war.
Gast #3708682
Lesenswert?
• ▲
▼
Genial, Danke!
Nach genau so einem Trick habe ich gesucht!

Ich gehe davon aus, dass es dann so aussehen muss
 ANDI temp, ~(1 << STAT0_PWRKEY)
 STS STAT0, temp
richtig?

SBI/CBI sind mir bekannt, aber wie man oben schon sieht, sind es nicht 
nur I/Os, sondern eben auch SRAMs bei denen einzelne Bits 
gesetzt/gelöscht werden sollen.
Gast #3708683
Lesenswert?
• ▲
▼
1<<0 = 0b00000001
1<<1 = 0b00000010
1<<2 = 0b00000100
1<<3 = 0b00001000
1<<4 = 0b00010000
1<<5 = 0b00100000
1<<6 = 0b01000000
1<<7 = 0b10000000

~(1<<0) = 0b11111110
~(1<<1) = 0b11111101
~(1<<2) = 0b11111011
~(1<<3) = 0b11110111
~(1<<4) = 0b11101111
~(1<<5) = 0b11011111
~(1<<6) = 0b10111111
~(1<<7) = 0b01111111
#3708697
Lesenswert?
• ▲
▼
Neuling schrieb:
> Nachtrag zum Nachtrag von /kbuchegg/
>
> Ich dachte quasi an sowas
>
1
> 1111 1111 Orig.
2
> 1111 1110 Null laden
3
> 1111 1101 ROL
4
> 1111 1011 ROL
5
> ...
6
>

Kannst du auch machen - wenn du dem Assembler beibringen könntest einen 
ROL zur Assemblierzeit zu machen :-)

Die << Operation füllt rechts immer mit 0 Bits auf. Daher geht dein 
Ansatz nicht.
#3708779
Lesenswert?
• ▲
▼
Karl Heinz schrieb:
> Einen Wert von 0 nach links
> zu verschieben ist daher eine sonnlose Operation

Logisch erfüllt es keinen Zweck, richtig. In bestimmten Fällen wende ich 
das "Schieben" einer Null wegen der Lesbarkeit des Codes trotzdem an. 
Zum Beispiel beim Setzen der Prescaler-Bits im Timer:

sbr  temp, (0<<CS22)|(0<<CS21)|(1<<CS20)    ;Vorteiler

So sieht man auf den ersten Blick, welche Bits gesetzt sind und welche 
nicht. Außerdem lassen sich schnell Änderungen vornehmen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.