www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bitweise auf PORT Ausgeben


Autor: Franz M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Franz M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ach noch vergessen: Ich progge in Assembler

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Route_66 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schieben, maskieren, logisch verknüpfen -> fertig!

Autor: Michael (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Michael (Gast)
Datum:

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

Autor: Mikki Merten (mmerten)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael (Gast)
Datum:

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

Autor: Franz M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok habs jetzt so. nicht schoen, nicht schnell, aber es geht:
  swap  count3
  lsr    count3
  lsr    count3
  cbi    PORTB, 0
  cbi    PORTB, 1  

  in    temp, PORTB
  or    temp, count3
  out    PORTB, temp

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

Danke fuer eure Hilfe!

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PORTB0,1 darf also zwischendurch seinen Zustand ändern???

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Über die ori-Zeile würde ich nochmal nachdenken. ;-)

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Franz M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael (Gast)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.def counter = r17

in r16, PORTB
bst counter, 6
bld r16, 0
bst counter, 7
bld r16, 1
out PORTB, r16

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:
>
> .def counter = r17
> 
> in r16, PORTB
> bst counter, 6
> bld r16, 0
> bst counter, 7
> bld r16, 1
> out PORTB, r16
> 


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

Merci für den Denkanstoss!

Autor: Franz M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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)...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.