PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu DDRx, PORTx, PINx



simple
10.10.2006, 08:37
Hi zusammen,

wie ich den Tutorials entnommen habe gehe ich doch folgendermaßen vor:

- wenn ich eine log. 1 oder 0 auf einen Pin legen möchte, setze ich das entsprechende Datenrichtungsregister z.B. DDRA |= (1<<PA2) und setze dann das entsprechende Pin z.B. PORTA |= (1<<PA2);

- wenn ich den Zustand von einem Pin lesen möchte, dann schalte ich das entsprechende DDR auf Eingang, also z.B. DDRA &= ~(1<PA2) und lese dann meinen Zustand ein, z.B: x = PINA & (1<<PA2).

- haben eigtl die "veralteten" Befehle inp() und outp() das DDR und das setzen des angegebenen Pins in einem Schritt gemacht?

Jetzt zur Frage: MUSS ich immer komplett die DDR auf jeweils Ein- oder Ausgang stellen bevor ich überhaupt etwas vom Pin lesen bzw. schreiben kann und welchen Aufwand hat diese Operation im µC? Ist sie atomar oder benötigt sie mehrere Rechenschritte? Gibt es schnellere Varianten?

Viele Grüße,
simple.

SprinterSB
10.10.2006, 08:54
Sollte wohl heissen DDRA &= ~(1<<PA2) ;-)

inp() und outp() konnten auch nicht mehr tun, als ein AVR kann... Die von die angegebenen C-Kommandow werden jeweils in eine Maschinen-Instruktion übersetzt, also sbi bzw cli.

DDRx kannst du entweder komplett auf Ausgang stellen (DDRx=0xff;) oder eben Pin-Weise, oder einzelne Pins anwählen:


DDRx |= (1<<Px2) | (1 << Px3);
Besser ist hier aber

DDRx |= (1<<Px2);
DDRx |= (1 << Px3);
letzteres wird zu 2 atomaren Instruktionen (sbi), während ersteres also Load-Modify-Store Sequenz ungesetzt werden muss (in, or, out), die nicht atomar ist.

Die normalen Operationen wie Port-Pin Lesen, Schreiben, als IN/OUT schalten werden jeweils als eine Instruktion umgesetzt.

Nicht atomar ist ein Toggle:


PORTx ^= (1 << Pxn);

https://www.roboternetz.de/wissen/index.php/Avr-gcc#Zugriff_auf_Special_Function_Registers_.28SFRs .29

simple
10.10.2006, 09:07
Danke für die Eklärung!

Nochmal zu meiner Frage oben: muss ich also immer zwingend die DDR-Register entsprechen auf in/out setzen wenn ich lesen/schreiben möchte?

Mir geht es darum, dass ich ein Bus-Protokoll implementieren möchte. Dazu muss ich erst den Bus ein paar mal auf high/low legen, d.h. ich setze das DDR meines Ports auf Ausgang und schreibe dann die entsprechenden 0er oder 1er mit PORTx |= ...
Dann will ich von den selben Pins lesen, d.h. ich muss das DDR auf Eingang stellen und denn kann ich via PINx die angelegten Zustände lesen?

Sind meine Überlegungen so richtig?
Oder kann ich eine angeschlossene Leitung auch ohne diesen Wechsel der DDR-Richtung auf high oder low ziehen?
Was genau bewirkt das setzen des DDR intern? Weil im endeffekt legt doch die Anweisung PORTx |= .. bzw. PORTx &= ... dann den entsprechenden Pegel auf den Port.

SprinterSB
10.10.2006, 11:01
AM bester verstehst du die Wirkung des DDR, wenn du dir im Handbuch den Blockschalt eines Ports anschaust. Da ist dann alles schematisch zusammengeschaltet: DDR, PORT, PUN, PUD, etc

Wenn du DDR auf IN stellst, dann legt PORT fest, ob der interne PullUp aktiv ist.

Bei deinem Protokoll musst du folgendes beachten: Wenn ein Fehler auftritt (beim Entwickeln nicht sooo selten) und 2 Ports von µC1 und µC2 kollidieren, dann kann es Schäden an der Hardware geben.

Alternativ könntest du den Port auf IN stellen und einen externen PU dranhängen.

Dann kannst du so was senden:
DDR=0, PORT=0 (passive HIGH (durch PU))
DDR=1, PORT=0 (active LOW)

Den PU extern, weil: Die internen sind recht groß und mit internem PU müsstest du umschalten zwischen
DDR=0, PORT=1
DDR=1, PORT=0

Wenn du erst den DDR schaltest kannst du einen Konflikt haben --> es raucht
Wenn du erst PORT schaltest, hängt der Pin kurz in der Luft.

Willst du ein One-Wire bauen?

simple
10.10.2006, 11:11
Ich sehe schon, dass ich erstmal diese Puill-Up/Down Geschichten verinnerlichen muss.



Willst du ein One-Wire bauen?


Da hat der Experte mich wieder durchschaut :)
Jetzt kommt bestimmt gleich die Frage, ob ich bereits bestehene Codeschnipsel verwende. Mein Problem: a) ist es teilweise mühselig zu verstehen, b) u.U. nicht ideal an mein Problem anzupassen, c) will ich dabei jede Menge lernen wie man selbst so ein Protokoll impelemtiert.

Aber falls Du hilfreiche Tips für 1W-Bus hast, freu ich micht natürlich immer sehr!

btw: externer Pullup scheidet aus, da die Schaltung auf der Platine fix ist.

simple
10.10.2006, 11:20
Im übrigen verstehst Du jetzt auch, warum ich mir Gedanken dazu gemacht habe, die DDRs "umzustellen" da ich ja beim 1W-Bus erst als Master den Bus sample und dann aber die samples die der Baustein auf den Bus legt lesen muss.

SprinterSB
10.10.2006, 16:22
Du hast ja auch interne PU an jedem Pin. Die Frage ist, ob deren Größe passt und sie nicht zu groß sind. AUsserdem weiß ich net wie stark die streuen.

Je größer die PUs, desto langsamer und unzuverlässiger wird es. Je kleiner, desto mehr Strom wird versenkt wenn du LOW bist.