PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PORTD DDRD PIND - Unterschiede?



toeoe
07.08.2005, 01:32
Hallo,

eine LED ganz einfach ansteuern kann ich schon. Und eine LED über einen Schalter ausmachen geht auch. Aber nun will ich, dass eine LED von Anfang an aus ist und ich sie über den Schalter anmache. (klingt einfacher als gesagt ;) )
Mein größtes Problem dabei ist glaube ich, dass ich nicht ganz weiß, was genau die Unterschiede zwischen DDRD, PORTD und PIND ist (genauso wie bei B oder C).

Das komische ist auch, dass D von 2-7 geht, aber B und C von 0-5. Muss ich das bei der Programmierung irgendwie berücksichtigen?
Achja, benutze das myAVR Board 1.4 :)

Vielen Dank schonmal und eine ruhige Nacht :)
Thomas

ProgDom
07.08.2005, 08:46
Also in DDRD legst du fest, ob es sich bei dem Port um einen Ausgang (0xFF) oder einen Eingang (0x00) handelt.
Wenn der Port als Ausgang deklariert ist, kann man über PORTD die Ausgänge schalten, z.B. mit 0xFF alle auf High.
Wenn PortD ein Eingang ist, kann man die anliegenden Pegel über PIND auslesen. Bei Eingängen ist es dabei wichtig die internen Pullup-Widerstände zu aktivieren. Dies geschieht indem man dann PortD auf High setzt.

Hier einmal ein kleiner Codeausschnitt:

ldi temp1, 0x00
out DDRC, temp1 ;PortC als Eingang

ldi temp1, 0xFF
out DDRD, temp1 ;PortD als Ausgang
out DDRB, temp1 ;PortB als Ausgang
out PORTC, temp1 ;Pullups von PortC aktivieren.

;--------------------

out PortB, r16 ;gibt an PortB das Byte r16

in r16, PinC ;schreibt in r16 das Byte, das anliegt !

;--------------------

Beispiel für deine Anwendung:

ldi r16, 0X00
out DDRD, r16 ;PortD als Eingang

ldi r16, 0xFF
out PortD, r16 ;Pullups
out DDRB, r16 ;PortB als Ausgang

main:
sbis PinD, 2 Liegt an D.2 high an ?
sbi PortB, 2 dann setze B.2
rjmp main:

SprinterSB
07.08.2005, 08:57
DDR: Data Direction Register(Richtung)
PIN: Port INput register


| DDRx.n=0 | DDRx.n=1
------------------------------------------------------
PORTx.n=0 | IN hochohmig (*) | OUT LOW (~ 20mA)
PORTx.n=1 | IN mit Pullup 20k-50k | OUT HIGH (~ 20mA)

(*) = default nach Reset

Den Wert bei IN kann in PINx.n gelesen werden
Bei OUT ist PINx.n = PORTx.n

Damit die LED von Anfang an leuchtet:

<pseudo-code>
DDRx.n=1 // Port als OUT
Falls LED zwischen Pad und GND:
PORTx.n=1
Falls LED zwischen Vcc und Pad:
PORTx.n=0
</pseudo-code>

Dani-Bruchflieger
07.08.2005, 09:31
Hi,

mir war beim Verständnis der Grundfunktionen die Artikelserie von Roland Walter im Funkamateur von 04/02-11/03 eine große Hilfe. Einige Artikel daraus sind auf seiner HP unter www.rowalt.de nachzulesen. Ansonsten gibt es von ihm auch ein Buch über den Mega8 mit Bascom.

Wie viele Anschlüsse ein Port am µC hat, kann man im Datenblatt des µC finden - steht gleich am Anfang gleich auf der 2. Seite oder manchmal noch auf der ersten.

Das DDRx und den PORTx kannst du auf verschiedene Weise einstellen:
DDRD=&B00001000 legt fest, daß nur PortD.3 Ausgang ist alle anderen Eingänge - diese Variante ist sehr sinnvoll, wenn man mehrere Ausgänge an einem Port benötigt - geht dann in einem Befehl.
alternativ geht auch &H für Hexcode oder &O für Oktal - &B für Binär finde ich hier aber übersichtlicher...
Die andere Variante ist auch über DdrD.3=1 nur den einen Anschluß als Ausgang zu konfigurieren.
Portx geht genauso zu konfigurieren, und hat am Ausgang die Funktion, daß es ihn auf High oder Low (1/0) schaltet. Am Eingang schaltet man mit Portx den Pullupwiderstand zu, der den Pin auf High-potential zieht, weil der Pin sonst wie eine Antenne wirkt, und schon schaltet, wenn man mit der Hand in die nähe kommt.
Mit Pinx.y fragt man den Zustand eines Eingangs-Pins ab. Das sollte evtl. sogar gehen, wenn der Pin als Ausgang konfiguriert war - bin mir da jetzt nicht sicher - mal probieren...


Edit: ähm ich sehe gerade, daß dein MyAVR nicht mit Bascom ist - Die Funktion der 3 Befehle ist wohl die selbe, aber bestimmt nicht das ansprechen mit zB portd=&B00010001. Dann wird dir die Seite von Roland Walter auch nicht wirklich weiterhelfen....

Jahn Kohlhas
07.08.2005, 10:31
Hallo,

also ich mache ne menge mit BASCOM und dem myAVR... geht prima ;-)

toeoe
07.08.2005, 11:20
Erstmal Danke an alle für die Antworten :)
Vorneweg, ich programmiere in Assembler, hätt ich vlt. dazu schreiben können, aber ich dacht ja, das wär hier auch das Forum, wo auch Assemblerfragen gestellt werden können, najo, auch egal ;)

@ProgDom:
Deine Variante funktioniert so weit. Also die LED ist am Anfang aus, und wenn ich den Taster drücke, dann geht sie an, allerdings bleibt sie dann auch an, wenn ich den Taster wieder loslasse. Was mir gra einfällt und natürlich noch besser wäre ist: ich drücke Taster --> LED an, ich drücke nochmal Taster --> LED aus, aber dann müsst ich ja irgendwie mit Variablen arbeiten, wo ich den aktuellen LED-Status speicher, oder? Oder denk ich da nun zu sehr an den Hochsprachen? Programmier nämlich sonst immer in C++.

Und was mir noch aufgefallen ist: Manchmal (unregelmäßig) ist die LED auch von Anfang an an, obwohl ich den Taster nich gedrückt habe, weiß aber net, an was das liegt, hmm...

Gruß
Thomas

[edit]
Nach langem hin und her hab ichs noch hinbekommen :)

;Definitionsdatei laden
.include "4433def.inc"

ldi r16, 0b00000000
;Inhalt von r16 ins IO-Register DDRD ausgeben -> PortD als Eingang
out DDRD, r16

ldi r16, 0b11111111
;Inhalt von r16 ins IO-Register DDRB ausgeben -> PortB als Eingang
out DDRB, r16
;Pullups von PortD aktivieren
out PORTD, r16

loop:
;Liegt an D.2 high an? Wenn nicht, dann nächsten Befehl überspringen
sbis PinD, 2
;Wenn ja, dann B.2 auf high setzen
sbi PortB, 2
;Liegt an D.2 low an? Wenn nicht, dann nächsten Befehl überspringen
sbic PinD, 2
;Wenn ja, dann B.2 auf low setzen
cbi PortB, 2
;Sprung zu "loop:" -> Endlosschleife
rjmp loop
Bleibt dann nur noch die Frage offen:
ich drücke Taster --> LED an, ich drücke nochmal Taster --> LED aus, aber dann müsst ich ja irgendwie mit Variablen arbeiten, wo ich den aktuellen LED-Status speicher, oder?
Aber dazu bin ich noch glaube ich zu sehr ein Newbie ;)