hi,
habe ien atmega 8, an PORTD sind 7 Schalter und an PIND7 eine
Datenleitung.
Also ich möchte gerne Daten senden und empfängen können an PIND7
hab mir das so gedacht:
Daten senden:
-----------------------------------------------------
DDRD = 0xFF alle als Ausgang
PORTD &= ~(1<<PORTD7) Bit löschen ->0
PORTD |= (1<<PORTD7) Bit setzen ->1
Daten empfangen:
--------------------------------------------------------
DDRD = 0x7F Ausgang nur DDD7 als Eingang
var = PIND7 Empfange Bit, 0 oder 1
ist das soweit richtig ? Hab keinen externen pull-up Widerstand.
In der Anleitung des anzusteuernden Sensors steht:
"To avoid signal contention the microcontroller should only drive DATA
low. An external pull-up resistor (e.g. 10 kΩ ) is required to pull
the signal high. Pull-up resistors are often included in I/O circuits of
microcontrollers."
Gruß Jan
> DDRD = 0x7F Ausgang nur DDD7 als Eingang
Warum machst Du es nicht genauso wie oben und änderst jeweils nur das
eine Bit, das geändert werden soll? Mach es doch mit
DDRD |= 1 << DDD7; //PortD.7 als Ausgang
DDRD &= ~(1 << DDD7); //PortD.7 als Eingang
Das Einlesen in var geht so nicht (PIND7 ist nur ein Makro). Und das
Bit solltest Du dann maskieren, um den Zustand der anderen Pins, den Du
ja nicht brauchst, zu ignorieren, also irgendwas wie
var = PIND & (1 << PIND7);
Dann entspricht Bit Nr. 7 in var genau dem eingelesenen Bit, die
anderen sind 0.
Vermutlich zerschießt Du Dir so Deinen Sensor. Du darfst, wenn der Pin
auf Ausgang geschaltet ist, auf keinen Fall eine "1" ausgeben!
Für dieses Problem fallen mir so spontan drei Workarounds ein:
1) Schau in das Datenblatt von Sensor und µC nach dem Maximal
zulässigen Strom und schalte einen Schutzwiederstand in die Leitung.
Zum Empfangen brauchst Du dann immer noch einen Pullupwiderstand.
2) Benutze am µC zwei Pins, den einen zum Senden, den anderen zum
Empfangen. An den Sendepin kommt dann ein Transistor als Schalter gegen
Masse.
3) Hänge einen Pullup an PortD7. Initialisiere PortD7 mit "0". Um
eine "0" auszugeben, setzt du das DDR auf Ausgabe. Wenn du das DDR
auf Eingabe schaltest, ist die Leitung durch den Pullup "1", es sei
denn, der Sensor zieht sie auf "0".
Mir fällt noch eine 4. Möglichkeit ein:
Benutze einen 8051-µC ;-)
Gruß,
Markus_8051
@Markus_8051:
Mit dem externen Pull-Up und der Beschreibung hast du sicher recht.
Ich hatte den Abschnitt unten mit dem Sensor gar nicht richtig zur
Kenntnis genommen...
Aber was bitteschön soll ein 8051er da besser können?
Wo ist der Nachteil? Indem man mit DDRxy statt PORTxy steuert, kann man
auch einen AVR-Port per open collector steuern. Nichts anderes macht
man beispielsweise bei OneWire oder auch bei I2C "zu Fuss".
Hey, war doch nur Spaß! Weiß ich doch, dass er das völlisch rischtisch
beschrieben hat. Nur sein abschließender Kommentar in seinem ersten
Posting hatte mein AVRler-Herz zutiefst getroffen, das konnte ich doch
so nicht stehen lassen...;-) [Ich hoffe es ist klar, dass auch dieser
Kommentar nicht ganz ernst gemeint ist...]
Im Datenblatt meines AVRs steht:
...If PORTxn is written logic one when the pin is configured as an
input pin, the pull-up resistor is activated.
To switch the pull-up resistor off, PORTxn has to be written logic
zero or the pin has to be configured as an output pin. The port pins
are tri-stated when a reset condition becomes active, even if no clocks
are running....
Das würde doch heissen, dass man den eingebauten PU aktiviert, wenn man
auf input schaltet und eine 1 ausgibt. Dadurch bekommt man am Sensor
ebenfalls 1. Für eine 0 muss man dann aber auf output schalten, da man
sonst hochohmig ist. Der eingebaute Widerstand ist angeblich zwischen
20 und 50 kOhm.
Wenn das für den Sensor passt - wäre das nicht eine Alternative ?