Da ich mich in den vergangenen Tagen ein bisschen mit den Eigenschaften verschiedener Datenbusse befasst habe, bei den elektrischen Grundlagen jedoch nicht gerade superfit bin, wollte ich einfach mal die elektrischen Eigenschaften des in meinen Augen einfachsten Busses testen, nämlich direkt miteinander per Kabel verbundener I/O-Pins eines Mikrocontrollers. Also habe ich ohne Rücksicht auf Verluste einfach mal die Pins PC0 bis PC3 meines Atmega8 per Drahtbrücken direkt miteinander verbunden. Ausser den direkten Verbindungen waren diese IO-Pins sonst mit nichts verbunden, also auch keine externen Pullup/Pulldown-Widerstände oder sowas. Dann habe ich einfach für jeden dieser vier IO-Pins jede Kombination von gesetzten/zurückgesetzten Bits des DDRC-/PORTC-/PINC-Registers getestet und geschaut ob das entsprechende PINC-Bit beim Auslesen danach gesetzt oder nicht gesetzt ist. Beispiel: DDRC : 0111 (PC0+PC1+PC2 = Output / PC1 + PC3 = Input) PORTC: 0101 (PC0+PC2 = high / PC1+PC3 = low) PINC>: 0011 (Interne Pullups von PC0+PC1 angeschaltet) ----------- PINC<: 1111 (Eingelesener Wert an allen Pins = 1) Das habe ich dann für alle (2^4)^3 möglichen Kombinationen ausprobiert und mir die Ergebnisse in eine Datei schreiben lassen. Nach kurzem Drüberschauen, jedoch ohne alle Ergebnisse überprüft zu haben meine ich folgende Zusammenhänge erkannt zu haben: Feststellung 1: PINC< (also der an allen Pins eingelesene Wert) ist immer gleich - "der auf dem Bus liegende Wert" wird also offenbar von allen IO-Pins gleich interpretiert, egal wie die Pins sonst konfiguriert sind (soweit schon mal gut) Feststellung 2: PINC> (also ob die internen Pullups ein- oder ausgeschaltet sind) scheint für das binäre "Ergebnis" PINC< vollkommen irrelevant zu sein Feststellung 3, Zusammenfassung: Der auf dem Bus liegende Wert (= PINC<) ist genau dann "0" wenn es unten allen als Output festgelegten IO-Pins (DDRCx = 1) MEHR Pins mit Low-Pegel gibt als mit Highpegel, ansonsten ist er "1" Beispiele: DDRC : 0011 PORTC: 0011 (zwei Ausgabepins mit high-Pegel) ----------- PINC<: 1111 (high-Pegel) DDRC : 1111 PORTC: 0101 (zwei Ausgabepins mit high, zwei mit low-Pegel) ----------- PINC<: 1111 (high-Pegel setzt sich durch) DDRC : 0111 PORTC: 0001 (ein Ausgabepins mit high, zwei mit low-Pegel) ----------- PINC<: 0000 (low-Pegel setzt sich durch) Nun würden mich folgende Dinge interessieren: - Sind diese von mir festgestellten Zusammenhänge grundsätzlich bei TTL-Pegeln so, oder liegt manches davon nur an den Eigenheiten meines Versuchsaufbaus? Anders ausgedrückt, würde/könnte sich etwas an diesen Zusammenhängen ändern, wenn z.B. statt der vier Pins am gleichen Mikrocontroller 13 IO-Pins an jeweils unterschiedlichen Mikrocontrollern benützt würden, die evtl. auch noch unterschiedlich weit voneinander entfernt sind? (Jedoch unter der Annahme, dass die entsprechenden Zustände/Signale lange genug (also z.B. 1 Sekunde) gehalten werden) - Macht es tatsächlich keinerlei Unterschied, ob die internen Pullups ein- oder ausgeschaltet sind? Zumindest irgendeinen elektrischen Unterschied muss es doch geben? - Was würde sich ändern (auch aus elektischer Sicht, wie z.B. Stromverbrauch oder so), wenn ich die benutzte Datenbusleitung zusätzlich noch mit einem Widerstand gegen GND und/oder VCC verbinden würde? (Auch mit eventuell leicht verändertem Versuchsaufbau wie etwas längeren Distanzen, Pins an verschiedenen Mikrocontrollern etc.) Ich habe gesehen dass bei vielen oder gar den meisten Bussen solche Widerstände benutzt werden, nur der Sinn ist mir noch nicht so ganz klar. Sorry für die vielen Fragen, bin schon dankbar wenn mir Jemand nur Teile davon beantworten kann - oder einen Link parat hat, der geeignet ist mir diese Fragen zu beantworten...
Verstehe ich das richtig, dass du ALLE 4 Portpins zusammen verbunden hast? Du hast also u.a. alle Pins als Ausgänge geschaltet und sie gegeneinander Treiben lassen, indem die Hälfte gegen Masse und die andere Hälfte gegen VCC geschaltet war. Da frage ich mich, ob du jetzt elektrische Eigenschaften eines Busses oder eher die Fehlbeschaltungs-Resistenz einer AVRs testen wolltest. Ein Bus macht nur dann Sinn, wenn immer maximal ein Teilnehmer als Ausgang definiert ist, während alle anderen "zuhören". Die Pullups machen auch sinn, die werden übrigens durch PORTC geschaltet, wenn ein Pin als Eingang definiert ist, vielleicht hast du dich ja nur verschrieben. Wenn du obiges beachtest (immer nur ein Ausgang gleichzeitig auf der Leitung), dann wird alles sehr viel einfacher zu überblicken.
"Du hast also u.a. alle Pins als Ausgänge geschaltet und sie gegeneinander Treiben lassen, indem die Hälfte gegen Masse und die andere Hälfte gegen VCC geschaltet war. Da frage ich mich, ob du jetzt elektrische Eigenschaften eines Busses oder eher die Fehlbeschaltungs-Resistenz einer AVRs testen wolltest." Ich wollte ersteres testen, eventuelle "Zerstörungen" habe ich lediglich in Kauf gewonnen. Bisher konnte ich allerdings auch keine Anzeichen von Zerstörung erkennen, von daher hatte ich hoffentlich Glück! "Ein Bus macht nur dann Sinn, wenn immer maximal ein Teilnehmer als Ausgang definiert ist, während alle anderen "zuhören"." Das stimmt so ja aber auch auch nicht 100%ig. Es kann ja durchaus vorkommen dass auf einem Bus zwei Devices gleichzeitig senden - ob das nun unerwünscht ist (Kollision) oder sogar erwünscht (bei bestimmten Arten des Busarbitrierung/Interruptpriorisierung). Natürlich ist der Regelfall, dass immer nur einer senden darf, aber es KANN ja durchaus vorkommen, dass mehr als einer zur gleichen Zeit sendet - daher wollte ich auch für solche Fälle testen, was passiert. "Die Pullups machen auch sinn, die werden übrigens durch PORTC geschaltet, wenn ein Pin als Eingang definiert ist, vielleicht hast du dich ja nur verschrieben." Nein, da hatte ich wirklich grad einen Denkfehler. Stimmt, die Pullups werden ja auch durch PORTC geschaltet. Dementsprechend macht es dann auch vollkommen Sinn, dass es egal ist was ich mittels "out PINC, x" ausgegeben habe - PINC ist ja ein Register, auf das eh nur nur lesender Zugriff Sinn macht, richtig? Zu welchem Zweck benutzt man denn nun bei Bussen externe Widerstände die gegen VCC und/oder GND verbunden sind? (in meinem Versuchsaufbau ging es ja auch ohne) Was könnte in meinem Versuchsaufbau an Schäden passieren, wenn mehr als einer gleichzeitig sendet?
eigentlich macht man das bei bussen doch so, dass garkeiner wirklich sendet, d.h spannung auf den bus gibt sondern nur den bus auf gnd ziehen darf. dadurch ist schon per definition ausgeschlossen, dass zwei gleichzeitg ihre ausgänge an den bus hängen. dann machen auch die widerstände einen sinn, denn das sollten dann die pull-ups sein, die den bus auf einem definierten high pegel halten, wenn gerad keiner sendet.
@Tobi: Dann gibt es für jedes IO-Pin x nur exakt zwei Konfigurations-Möglichkeiten, sehe ich das richtig? DDR?x = 1 / PORT?x = 0 : Pin als Ausgang, Pegel des Busses wird auf GND gezogen -> Alle Ports lesen einen logischen "0"-Pegel DDR?x = 0 / PORT?x = 1 : Interne Pullups eingeschaltet, Pin als Input definiert -> Sofern kein anderer Pin den Pegel auf GND zieht, liest jeder eine logische "1" Entspricht das dann nicht einem "wired-and" (lang lang ist's her, dass ich das mal gelernt habe), wenn dann doch zwei oder mehr gleichzeitig "senden", also den pegel auf GND ziehen? Und noch weitere Fragen: Genügt ein einziger gegen GND ziehender Output-Pin, um den Pegel des ganzen Busses sicher auf einen low-level zu ziehen - egal wieviele Pins an den Bus angeschlossen sind etc.? Was für einen Unterschied würde es machen, wenn die Pins im "Input-Modus" den internen Pull-Up ausschalten, dafür jedoch ein externer Pullup-Widerstand zwischen der Datenbusleitung und VCC liegt? Macht ein externer Widerstand zwischen Datenbusleitung und VCC bei EINGESCHALTETEN internen Pullups irgend einen Sinn? Macht ein externer Widerstand zwischen Datenbusleitung und GND hier irgend einen Sinn?
> DDR?x = 0 / PORT?x = 1 : Interne Pullups eingeschaltet, Pin als Input > definiert -> Sofern kein anderer Pin den Pegel auf GND zieht, liest > jeder eine logische "1" Nein. Eine Voraussetzung für solche Busse ist die Fähigkeit der Teilnehmer, ihre Pins in den Tristate-(High-Impedance)-Modus zu schalten. Beim AVR geht das, indem man DDxn auf 0 und PORTxn ebenfalls auf 0 setzt (siehe Datenblatt). Der Bus benötigt dann natürlich externe pullup-Widerstände. Externe Widerstände haben ganz einfach den Vorteil, dass der Bus eine bestimmte Geschwindigkeit immer halten kann; die Maximalgeschwindigkeit hängt nämlich z.T. von den Widerständen ab. Wenn nun jeder Teilnehmer eigene Pullups benutzen würde, würde schon bei wenigen Pins ein ziemlich großer Strom fließen. Zudem wäre der Gesamtwiderstand unberechenbar und unstabil (variiert mit der Anzahl der Teilnehmer). Ich empfehle dir "The Art of Electronics", Band 2.
Vielen Dank, Chris! Ich denke jetzt habe ich es verstanden, ich fasse mal zusammen: Man verbindet alle IO-Pins, die an den Bus angeschlossen werden sollen, mit einer Leitung. Ausserdem wird noch ein Pullup-Widerstand zwischen diese Leitung und VCC gehängt, damit auch wenn keiner sendet der Bus einen definierten Pegel (1) hat. Der Wert des PORT?x - Registers aller an den Bus angeschlossenen Pins ist IMMER 0. Im normalen (nicht sendenden) Modus wird das DDR?x-Register auf 0 gesetzt (Eingang, da PORT?X = 0 / interner Pullup nicht aktiviert -> Hochohmig). Schreiben kann man auf den Bus indem man das DDR?x-Register auf 1 setzt (Ausgang, da PORT?x = 0 -> Ausgang auf Masse). "Auf den Bus schreiben" bedeutet immer eine logische 0 zu schreiben. Schreiben mehrere auf einmal auf den Bus, so ist das (bei dieser Beschaltung) auch elektrisch betrachtet kein Problem. Der Bus hat immer logischen 0-Pegel, sobald mindestens einer gleichzeitig "schreibt" - nur wenn keiner "schreibt" liegt eine logische 1 an. 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.