Forum: Mikrocontroller und Digitale Elektronik Bitweise auf PORT Ausgeben


von Franz M. (Gast)


Lesenswert?

Hi,
die Frage ist mir ja fast schon peinlich, aber gibt es eine EINFACHE 
(2-3 Zeiler) Möglichkeit, die Bits 6 und 7 einer Variable (in meinem 
Fall "counter") auf den PORTB PB0 und PB1 auszugeben (also 6->PB0, 
7->PB1), OHNE PB2...PB7 zu beeinflussen?

Ich könnte jetzt pruefen, ob die Bits gesetzt sind und je nach dem an 
eine Sprungmarke springen und den entsprechenden Port mit SBI bzw. CBI 
setzen bzw. loeschen.

Aber das muss doch einfacher gehen oder nicht!?

Sorry fuer meine auf-dem-Schlauch-Steherei ;-)

Danke
Franz

von Franz M. (Gast)


Lesenswert?

ach noch vergessen: Ich progge in Assembler

von Karl H. (kbuchegg)


Lesenswert?

Franz M. wrote:
> ach noch vergessen: Ich progge in Assembler

die beiden Bitposition von counter mittels einer AND Maskierung 
freistellen. Um 6 Positionen nach unten schieben. PORTB einlesen, PB0 
und PB1 definiert auf 0 setzen. Die vorher geschobenen beiden Bits mit 
einem Oder drüberschreiben. Das Resultat wieder auf PORTB ausgeben.

->   die Lösung mit cbi/sbi dürfte einfacher sein. Vor allem das 
Schieben um 6 Positionen wird viel Zeit verschlingen.

von Route_66 (Gast)


Lesenswert?

schieben, maskieren, logisch verknüpfen -> fertig!

von Michael (Gast)


Lesenswert?

Wieso um 6 Stellen schieben? Ich komm auf drei, einfach durchs Carry 
schieben, man kann ja nach links und rechts schieben ;)

von Karl H. (kbuchegg)


Lesenswert?

Michael wrote:
> Wieso um 6 Stellen schieben? Ich komm auf drei, einfach durchs Carry
> schieben, man kann ja nach links und rechts schieben ;)

Hast recht.
(Ich hol mir jetzt noch einen Kaffee)

von Michael (Gast)


Lesenswert?

Hihihi, na dann. Denke aber auch, dass die Bit-Operation SBI/CBI 
schneller sein würden.

von Mikki M. (mmerten)


Lesenswert?

Quick and dirty

R16 = Variable

    sbrc    R16,6
    sbi     PORTB,0
    sbrs    R16,6
    cbi     PORTB,0
    sbrc    R16,7
    sbi     PORTB,1
    sbrs    R16,7
    cbi     PORTB,1

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Die Lösung wird auch davon abhängen, wo man atomar sein will/muss

-- wenn man an den Ausgängen atomar sein muss, also Zwischenzustände 
vermeiden, die man garnicht ausgeben will, muss man auf den ganzen Port 
schreiben und sbi/cli ist obsolet

-- wenn man intern atomar sein muss, weil auch eine ISR auf dem Port 
rumnudelt, dann ist ein Lesen/Schreiben des Ports problematisch: Es muss 
dann in cli/sei o.ä. oder man nimmt die sbi/cli-Lösung.

Johann

von Michael (Gast)


Lesenswert?

Nun, da der TE nichts dergleichen erwähnte ist es wohl irrelevant. Man 
muss ja Aufgaben nicht verkomplizieren ;)

von Franz M. (Gast)


Lesenswert?

Ok habs jetzt so. nicht schoen, nicht schnell, aber es geht:
1
  swap  count3
2
  lsr    count3
3
  lsr    count3
4
  cbi    PORTB, 0
5
  cbi    PORTB, 1  
6
7
  in    temp, PORTB
8
  or    temp, count3
9
  out    PORTB, temp

Es fehlt einfach der richtige Befehl :(
(Bit setzen in Abhaengigkeit eines anderen Bits oder sowas :P )

Danke fuer eure Hilfe!

von Michael (Gast)


Lesenswert?

PORTB0,1 darf also zwischendurch seinen Zustand ändern???

von Karl H. (kbuchegg)


Lesenswert?

Ist garantiert, dass in count3 keine anderen Bits gesetzt sind?

  swap  count3
  lsr   count3
  lsr   count3
  in    temp, PORTB
  andi  count3, 0x03
  ori   temp, 0x03
  or    temp, count3
  out   PORTB, temp

von Stefan E. (sternst)


Lesenswert?

Über die ori-Zeile würde ich nochmal nachdenken. ;-)

von Michael (Gast)


Lesenswert?

Hm, und immer noch ein 8-Zeiler. Mikki Mertens Vorschlag scheint mir die 
beste Lösung zu sein werden doch nur Bits gesetzt, die gesetzt werden 
sollen und man benötigt auch weiteren Variablen ;)

von Franz M. (Gast)


Lesenswert?

Ich merke grade, dass das oben von mir ja gar nicht funktioniert!
Die nach dem SWAP sind die 4 low-bits ja im high-nibble und werden dann 
mit ver-odert.

Aber man kann ja eh nicht "gleichzeitig" beide PBs aendern, ohne wie 
gesagt auf den ganzen PORTB zu schreiben. Also hat man immer einen 
"undefinierten" Zustand zwischendurch.
Oder halt ziemlich großen Aufwand....

Ich mach jetz erstmal Fruehstueck und danach schreib ich euch meine 
Loesung

von Michael (Gast)


Lesenswert?

Wie gesagt, nimm den von Mikki Merten oben, da haste immer einen 
definierten Zustand ;)

von Johannes M. (johnny-m)


Lesenswert?

1
.def counter = r17
2
3
in r16, PORTB
4
bst counter, 6
5
bld r16, 0
6
bst counter, 7
7
bld r16, 1
8
out PORTB, r16

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst wrote:
> Über die ori-Zeile würde ich nochmal nachdenken. ;-)

Grrrrr. Brauch gleich noch einen Kaffee.
Beim Überlegen war das noch anders. Aber die Finger haben dann
ganz was anderes geschrieben.

  swap  count3
  lsr   count3
  lsr   count3
  in    temp, PORTB
  andi  count3, 0x03
  andi  temp, 0xFC
  or    temp, count3
  out   PORTB, temp

von Karl H. (kbuchegg)


Lesenswert?

Johannes M. wrote:
>
1
> .def counter = r17
2
> 
3
> in r16, PORTB
4
> bst counter, 6
5
> bld r16, 0
6
> bst counter, 7
7
> bld r16, 1
8
> out PORTB, r16
9
>


Das ist trickreich :-)
Endlich hab ich mal verstanden, was so typische Einsatzfälle für das 
T-Flag sind.

Merci für den Denkanstoss!

von Franz M. (Gast)


Lesenswert?

ja das is echt tricky :P

Wenn sich jetzt nicht zwischen "in r16, PORTB" und "out PORTB, r16" was 
am PORTB aendert, ist alles OK ;-)

Danke euch

von Johannes M. (johnny-m)


Lesenswert?

Karl heinz Buchegger wrote:
> Das ist trickreich :-)
> Endlich hab ich mal verstanden, was so typische Einsatzfälle für das
> T-Flag sind.
Naja, ich finde, bst und bld fristen zu Unrecht ein Nischendasein. 
Ich vermute fast, dass sich selbst erfahrenere Assembler-Programmierer 
der Existenz dieser beiden Befehle oft übehaupt nicht bewusst sind. Ich 
finde die aber oft ziemlich praktisch. Wie oft hat man das Problem, dass 
man Bitzustände irgendwo herbekommt und in einer völlig anderen 
Reihenfolge woanders augeben muss. Und wie man sieht, gibt es bei 
wenigen Bits sogar bei Beibehaltung der Reihenfolge Codegrößen- und 
Performance-Vorteile.

Ich musste es aber auch erst hinschreiben, um zu sehen, dass es 
tatsächlich kürzer ist als die anderen Vorschläge. Habe schon ziemlich 
lange nichts ernsthaftes mehr in Assembler programmiert...

> Merci für den Denkanstoss!
Keine Ursache. Weiß nicht, wie oft ich schon Denkanstöße von Dir 
bekommen habe (und ich glaube, das geht den meisten, die sich schon 
länger hier im Forum rumtreiben, so)...

von Johannes M. (johnny-m)


Lesenswert?

Franz M. wrote:
> ja das is echt tricky :P
>
> Wenn sich jetzt nicht zwischen "in r16, PORTB" und "out PORTB, r16" was
> am PORTB aendert, ist alles OK ;-)
Das Problem haste bei Read-Modify-Write-Zugriffen dummerweise immer. In 
dem Falle wäre tatsächlich die Methode mit sbi und cbi die einzig 
empfehlenswerte. Die ist aber länger...

EDIT:
OK, meist genügt es natürlich, für die Zeit vom in bis zum out die 
Interrupt-Bearbeitung zu sperren. Nur wenn irgendwelche Hardware (Timer, 
serielle Interfaces) auf PORTx zugreifen, genügt das nicht mehr.

von Peter D. (peda)


Lesenswert?

Johann L. wrote:
> Die Lösung wird auch davon abhängen, wo man atomar sein will/muss
>
> -- wenn man an den Ausgängen atomar sein muss, also Zwischenzustände
> vermeiden, die man garnicht ausgeben will, muss man auf den ganzen Port
> schreiben und sbi/cli ist obsolet

Ganz genau umgekehrt ist es richtig, man muß SBI/CBI nehmen, um atomar 
zu sein!

Nimmt man IN,AND,OR,OUT ist das nicht mehr atomar.
Dann muß mit CLI/SEI geklammert werden, wenn auch Interrupts den Port 
benutzen.


Peter

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter Dannegger wrote:
> Johann L. wrote:
>> Die Lösung wird auch davon abhängen, wo man atomar sein will/muss
>>
>> -- wenn man an den Ausgängen atomar sein muss, also Zwischenzustände
>> vermeiden, die man garnicht ausgeben will, muss man auf den ganzen Port
>> schreiben und sbi/cli ist obsolet
>
> Ganz genau umgekehrt ist es richtig, man muß SBI/CBI nehmen, um atomar
> zu sein!
>
> Nimmt man IN,AND,OR,OUT ist das nicht mehr atomar.
> Dann muß mit CLI/SEI geklammert werden, wenn auch Interrupts den Port
> benutzen.
>
>
> Peter

ALLES lesen, was ich schrieb :-)

Ein wenn sich das "atomar" auf die Signale bezieht (keine seltsanmen 
Zwischenzustände), heisst das wohl "glitch" oder so im Fachchinesisch?

Beispiel: mit sbi/cbi kommt man nicht ohne Zwischenzustand von 00 nach 
11 oder 01 nach 10 etc.

Das ist u.a. auch dann von Belang, wenn im Programm nicht asynchron auf 
die Ports gegriffen wird.

Wenn asynchron auf die Ports gegriffen wird, dann "atomar" mit sbi/sbi 
wie ich schon schrieb.

Beispiel: In der Anwendung werden .0 und .1 gesetzt, in einer ISR .6. 
Dann braucht man cli/sei.

Johann

von Peter D. (peda)


Lesenswert?

Johann L. wrote:

> ALLES lesen, was ich schrieb :-)
>
> Ein wenn sich das "atomar" auf die Signale bezieht (keine seltsanmen
> Zwischenzustände), heisst das wohl "glitch" oder so im Fachchinesisch?

Du kannst nicht einfach dem Begriff "atomar" ne falsche Bedeutung geben.
Wenn Du glitch meinst, dann ist das was völlig anderes als atomar.

Atomar bedeutet nicht unterbrechbar, hat mit Glitches überhaupt nichts 
zu tun.
Nicht atomar ist etwas, wenn ein Interrupt dazwischen haut und dann die 
Änderung des Interrupts verloren geht.


> Beispiel: mit sbi/cbi kommt man nicht ohne Zwischenzustand von 00 nach
> 11 oder 01 nach 10 etc.

Das hat überhaupt nichts mit "atomar" zu tun, ist ne völlig andere 
Baustelle.

Gleichzeitig ist eh nie ein Wechsel zweier Signale, Du hast immer 
unterschiedliche Schaltzeiten und wenn es nur Picosekunden sind.
Wenn Du das willst, mußt Du Graycode nehmen oder die Signale mit einem 
Takt latchen, nachdem sie stabil sind.

Schau Dir mal die NXP ARM7-TDMI an, die haben getrennte Set- und 
Clear-Register, d.h. Du kannst dort nichtmal im gleichen Maschinenzyklus 
mehrere Pins setzen und löschen.
Sie sind aber extra dazu eingeführt worden, um atomar zuzugreifen, da 
bei den ARM7 ein Interrupt-Disable eine ziemliche Verrenkung ist (nicht 
im Usermode möglich).

Sowohl atomar als auch (fast) gleichzeitig kann der ARM-Cortex M3, da er 
spezielle Bitbefehle hat.


Peter

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter Dannegger wrote:
> Johann L. wrote:
>> Beispiel: mit sbi/cbi kommt man nicht ohne Zwischenzustand von 00 nach
>> 11 oder 01 nach 10 etc.
>
> Das hat überhaupt nichts mit "atomar" zu tun, ist ne völlig andere
> Baustelle.

Schon klar. Mir fehlt(e) da lediglich eine Vokabel. Wie heisst es denn 
korrekt?

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.