PORT und DDR... und PullUps

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.090
57
48
Hennigsdorf
Sprachen
BascomAVR, Assembler
Hallo,

bisher kennen wir das bei den AVRs ja so:
  • fürs lesen eines Beinchens kann man ein Bit in einem PIN-Register auslesen
  • den Pegeltreiber kann man mit einem Bit im Datenrichtungsregister (DDR) an-/abschalten
  • den Pegel selbst mit dem Bit im Port-Register festlegen
Bei einem Ausgang (DDR.x=1) wird dabei der Pegel direkt auf Vcc/Gnd geschaltet, bei einem Eingang (DDR.x=0), also wenn der Treiber aus ist, und somit der Pin eigentlich (immer) Tristate wäre, wird mit PORT.x=1 jetzt automatisch der interne Pullup auf Vcc gelegt.
Es sei denn, man deaktiviert die Pullups global.
Hintergrund ist, daß der Pullup über ein 3fach-AND-Gatter aktiviert wird, in welches das PORT-Bit, das invertierte PIN-Bit und das invertierte globale PullUp-disable-Bit einfliessen.

So kennen und verwenden wir das bisher.

Im Datenblatt des Tiny441/841 bin ich jetzt aber auf einen abweichenden Aufbau der generellen Pin-I/O gestossen:
hier existiert dieses AND-Gatter nicht, stattdessen gibt es für jeden Pin ein Bit in einem Pullup-Enable-Register.

Was bedeutet das? Daß mit DDR.x=0 und Port.x=1 nicht mehr automatisch der Pullup aktiviert wird. Ok Dazu wird jetzt eben PUEx.n verwendet, ABER:
  • Dann kann man den Pullup nicht mehr durch beschreiben des PIN-Register-Bits mit einer 1 toggeln (da sich das ja auf das PORT-Register auswirkt.
  • PUEx befindet sich im extendet-I/O, ist also nicht mit IN/OUT erreichbar, und erst recht nicht mehr direct-bit-accessible.
Außerdem kann man so auch den (ausdrücklich nicht empfohlenen) Zustand: Portx.n=0, DDRx.n=1 (also Ausgang, low Pegel/Gnd - Pin über den Treiber intern mit Gnd verbunden) und PUEx.n=1 (Pin über den Pullup intern mit Vcc verbunden) einstellen. Dann fließt intern Strom von Vcc über den Pullup und den Treiber nach Gnd. 'ne Chip-Heizung sozusagen...

Dieser Tiny besitzt also zum Einstellen des Pins 3 Register (Bits):
  • DDRx.n zum einstellen der Datenrichtung (Treiber an-/abschalten)
  • PORTx.n zum festlegen des (aktiven) Pegels (nur wenn der Treiber aktiv ist)
  • PUEx.n zum aktivieren des Pullups
Möglicherweise werden einige neuere AVR dann auch diese Bein-Architektur aufweisen...
 

TommyB

Premium Benutzer
17 Mai 2010
1.755
63
48
35
127.0.0.1 ;)
Sprachen
Assembler, LunaAVR, VB.Net, Python, C#
Dann kann man den Pullup nicht mehr durch beschreiben des PIN-Register-Bits mit einer 1 toggeln (da sich das ja auf das PORT-Register auswirkt.
Ich kenn diesen Chip jetzt nicht aber ich kenn das eher so:

Ausgang:
DDR Bit 1
PORT Bit steuert das Beinchen (ich sage jetzt extra nicht "Pin" um Missverständnisse zu vermeiden)

Eingang:
DDR Bit 0 (ist eh schon Default)
PIN Bit liest den Status aus
PORT Bit schaltet den PullUp an oder aus. Die PIN Register sind bei den AVR's die ich nutze überall read-only. Gut möglich dass es über das schreiben des Bits im PIN Register getoggelt wurde (nie probiert) aber man soll doch auch nicht im read-only Speicher schreiben. Atmel würd dir auf die Finger haun :p

Das Datenblatt hab ich mir jetzt noch nicht angeschaut. Gut möglich dass so eine Situation eintreten kann. Wenn ja... Vielleicht könnt man die ja dazu nutzen den internen Temperaturfühler den einige AVRs haben zu eichen, so ganz ohne externe Beschaltung ^^
Oder das PUD Bit wird intern ohnehin deaktiviert wenn das Beinchen n Ausgang ist. So würde diese Situation nie eintreten. Müsste man vielleicht mal testen. Datenblätter sind auch nicht immer fehlerfrei. In solchen Fällen erwähne ich immer gerne wieder an eine perfekt ins deutsche übersetzte Frage aus dem MCSA Kurs: "Wie prüft man ob die brennende Wand aktiviert ist?"

Oder hab ich da nu was falsch verstanden? 0.o
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.090
57
48
Hennigsdorf
Sprachen
BascomAVR, Assembler
Hmm...
...
bisher kennen wir das bei den AVRs ja so:
  • fürs lesen eines Beinchens kann man ein Bit in einem PIN-Register auslesen
  • den Pegeltreiber kann man mit einem Bit im Datenrichtungsregister (DDR) an-/abschalten
  • den Pegel selbst mit dem Bit im Port-Register festlegen
Bei einem Ausgang (DDR.x=1) wird dabei der Pegel direkt auf Vcc/Gnd geschaltet, bei einem Eingang (DDR.x=0), also wenn der Treiber aus ist, und somit der Pin eigentlich (immer) Tristate wäre, wird mit PORT.x=1 jetzt automatisch der interne Pullup auf Vcc gelegt.
Es sei denn, man deaktiviert die Pullups global.
Hintergrund ist, daß der Pullup über ein 3fach-AND-Gatter aktiviert wird, in welches das PORT-Bit, das invertierte PIN-Bit und das invertierte globale PullUp-disable-Bit einfliessen.

So kennen und verwenden wir das bisher.
...
wie gesagt - bisher...
mal ein Bild zu diesem Sachverhalt (Datenblatt des Mega48/88/168 - aber auch in vielen anderen):
Screenshot_2014-03-09-19-24-19.png
Der Pullup wird mit Vcc verbunden (also "aktiviert") genau dann wenn:
  • Die (alle) Pullups NICHT global disabled sind (PUD-nicht gesetzt) UND
  • das DDR-Bit nicht gesetzt ist (Eingang) UND
  • das PORT-Bit gesetzt ist
'N 3fach-AND-Gatter, mit teils invertierten Eingängen...

Beim Tiny441 sieht die Architektur des Beinchens und seiner Register jetzt aber so aus:
Screenshot_2014-03-09-19-26-21.png
Das Gatter fehlt, das globale PUD für alle Pullups auch, stattdessen gibt es jetzt für jedes Bein ein seperates PullupEnableBit, welches unabhängig von den anderen Registern in einem eigenen Register gesetzt/löscht wird. Diese Register (2 für 2 Ports) liegen aber im extendet I/O-Space.
[HR][/HR]
Das mit dem Schreiben von Einsen ins PIN-Register ist schon richtig so, und auch (bisher) in allen(*) Datenblättern zu finden...
Toggling the pin
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port.
Wird eine 1 in ein Bit eines PIN-Registers geschrieben ((indirekt) über das SRAM, direkt über das I/O oder ganz direkt mit SBI), wird nicht das (readonly) PIN-Register manipuliert, sondern das korrespondierende PORT-Register-Bit getoggelt. Unabhängig davon, ob das Bein überhaupt mit den Register-Bits verbunden ist (siehe unser Software-UART-Thread, wo ich das Paritätsbit eben genau auf diesem Wege im PORT-Bit des Reset-Pins zusammengetoggelt hatte...).
Auf das Beinchen wirkt es sich natürlich nur/erst dann aus, wenn es mit den Registern verbunden ist (Stichwort alternate port functions)

(*) Korrektur: "in allen moderneren" - siehe jeweiliges Datenblatt -> "Toggling the Pin" ;)
 
Zuletzt bearbeitet:

TommyB

Premium Benutzer
17 Mai 2010
1.755
63
48
35
127.0.0.1 ;)
Sprachen
Assembler, LunaAVR, VB.Net, Python, C#
Haste Recht 0.o
Da war Atmel denn wohl nicht grade konsequent in ihren Datenblättern, weil:
ATmega 48, 88, 168.pdf (SECURED) - Foxit Reader.png
Hatten wir also quasi beide Recht. Wusste ich nicht dass das geht (ich habs ja aber auch nicht geleugnet).

Vermutlich war das auch mit ein Punkt der dein Code (Soft UART) für mich schwerer verständlich gemacht hatte. Einfach weil ich es nicht wusste (und selber dementsprechend auch nie so machen würde, aber viele Wege führen nach Rom ;))
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.090
57
48
Hennigsdorf
Sprachen
BascomAVR, Assembler
..war Atmel denn wohl nicht grade konsequent in ihren Datenblättern...
Ansichtssache, die Schreiboperation hat ja keinen Effekt auf das Pin-Register...
Aber egal. Jetzt weißte's (Ob Du es nun jemals brauchst, oder nicht...)

Aber zurück zum eigentlichen Thema:
In praktisch allen Tutorials wird zum Thema Taster mit internen Pullups eben logischerweise der Pin als Eingang konfiguriert (dafür gibts'n Config-Befehl), und dann über das Port-Register der Pullup zugeschaltet (dafür scheints keinen Config Befehl zu geben, zumindest nicht unter Bascom, oder?).
Bisher war das Ergebnis auch auf andere Controller portierbar - beim 441 müßte für den Pullup jetzt aber auf ein anderes Register verwendet werden (PUEx eben). Du kannst aber auch nicht überall suchen und ersetzen, denn für den Pegel selbst bleibt das PORT-Register ja weiterhin relevant. Da Bascom nicht weiß, wann Du den Pegel, und wann den Pullup manipulieren willst (zumindest nicht immer), kann das nicht so einfach automatisiert werden, sondern muß im Einzelfall durchgegangen werden. (insbesondere, wenn sich das erst zur Laufzeit entscheidet - zB wenn (warum auch immer) irgendwelche äußeren Umstände darüber entscheiden)

Das ächste Problem könnte in irgendwelchen Software-Routinen entstehen, die den Pullup vewenden (gibts sowas?), und die Du mit irgend'nem Config einbindest, die sich dann auch fehlerlos compilieren lassen (der hat ja das manipulierte Port-Register), aber dann eben nicht wie gefordert den Pullup verwenden -> zack, nicht verständliches fehlverhalten.

Unterstützt Bascom den Tiny441?

Aber auch der ASM-ler schaut bei der Bein-Configuration ja nicht mehr ins Datenblatt (wer denkt denn schon daran, daß der Tiny so'ne grundlegend andere Architektur hat), und wundert sich dann, warum der interne Pullup "durchgebrannt" ist...
(Ich hab das jetzt auch nur zufällig gefunden).

Ok denkst Du jetzt vielleicht, das ist nur ein Chip, wen interessiert der schon?
Immerhin ist das ein 14pin-Tiny mit 4 bzw 8k Flash.
Der läßt sich also als SOIC noch problemlos verlöten
Und er hat ganz brauchbare Schnittstellen (2xUART, TWI, SPI), 3 Timer (mit je 2 OC-Units) usw.

Und außerdem vermute ich, daß uns diese Architektur der I/O-Ports in Zukunft noch öfter begegnen wird.
Bei den OC-Outputs scheint man auch nicht mehr auf feste Pins angewiesen zu sein, sondern kann mehrere auf das OC-Unit "aufschalten" .
 

achim S.

Premium Benutzer
16 Jan 2010
442
6
18
Nähe Basel
Sprachen
C
Hallo zusammen
Du hast mich mit dem PUE richtig neugierig gemacht. Im Moment schnalle ich es noch nicht. Könntest du es vielleicht an einem Beispiel erklären?
achim
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.090
57
48
Hennigsdorf
Sprachen
BascomAVR, Assembler
Mal von vorn...

Als erstes nimmst Du Dir das erste Bild aus #3 vor; also die Ansteuerung bei den konventionellen AVR (DDRxn/PORTxn):
Und jetzt vergißt Du mal spontan alles was Du über Eingänge, Ausgänge usw zu wissen glaubst...

7993


1) Das Kästchen Pxn ist das eigentliche Bein

2) Der lange vertikale Pfeil rechts stellt den Datenbus dar


Über den Bus kannst Du auf das Bein "zugreifen", indem Du folgende drei Register(-Bits) liest oder schreibst


3) Ist das Datenrichtungsregister DDRx (bzw nur das eine Bit davon, welches zum konkreten Bit gehört - DDRxn) - das "Richtung" vergessen wir wie gesagt...

4) Ist das PORT Latch Register (bzw nur ein Bit daraus - PORTxn)

5) Ist das PORT Input Register (auch nur ein Bit, klar - PINxn)



Betrachten wir erstmal den Weg vom Bein über das PINxn zum Bus:
7994

Der Zustand liegt immer am Synchronizer (5B) an, es sei denn der Controller befindet sich im Sleep-Mode. Dann würde der Block (5A) Intern auf Gnd gehalten werden.
Der Synchronizer synchronisiert auf den Systemtakt (clk I/O).
Zwischen (5A) und (5B) befindet sich außerdem ein Schmitt-Trigger.
Die Information über den Pegel des Beines kann (außer im Sleep ;)) jederzeit (also unabhängig von irgendeiner Datenrichtung) aus dem Synchronizer gelesen werden (in den Bus): Das Signal RPx (Read Port x Pin) schaltet den Treiber bei (5C) transparent, der Ausgang des DQ-Latches (PINxn) landet auf dem Bus...

Zum Data-Direction-Bit (DDxn):

7995

Der Zustand des Data Direction Bit legt in erster Linie den Zustand des Ausgangstreibers des Beines (3A) fest. Bei einer "0" ist der Treiber inaktiv, bei einer "1" aktiv. DDxn könnte man also auch als Pin Output Driver Enable verstehen (PODE ? ).
Beim beschreiben von DDxn sorgt das WDx-Signal (write DDRx) dafür, daß der Zustand des Busses in das DQ-Latch (3) übernommen wird, andersrum kann der Zustand des Latches (also auch der des Treibers (aber nicht der des Beines)) in den Bus zurückgelesen werden - RDx (read DDRx) schaltet den Treiber (3B) transparent.

Welcher Pegel am Eingang des Port Ausgangs Treibers (3A) (und bei aktiviertem Treiber (nur dann) folglich auch am Bein selbst(1)) anliegt, bestimmt das PORTxn-Bit (4):

7996

Auch dieses Bit wird über den Bus beschrieben (Schreib-Signal ist hier das "Write Portx Register-Signal" WRx), es kann auch zurückgelesen werden (Lese-Signal ist das "read PORTx Register-Signal" RRx)

Das WPx-Signal ("Write PINx Register") beschreibt nicht das PIN-Register, stattdessen wird, wenn das zu schreibende Bit auf dem Datenbus "1" ist, der Ausgang des DQ-Latches invertiert (der Inverter direkt über dem Latch) auf den eigenen Eingang zurückgekoppelt - schreibt man also eine "1" in ein PIN-Register-Bit, toggelt das dazugehörende PORT-Register-Bit.
Das ist aber nicht bei allen klassischen AVR so - bei meiner Tiny-Übersicht gibt's dafür die Spalte "Pin-Toggling"


Und wie ist das jetzt mit dem internen Pullup?

7997

Der Widerstand (6) ist quasi immer mit dem Bein(1) verbunden, aber er wird nur dann zum Pullup, wenn der Transistor (6A) durchschaltet (auf Vcc).
Und das wiederum geschieht durch den Ausgang des Dreifach AND-Gatters (6B).
Der Transistor schaltet das Bein über den Pullup auf Vcc, wenn folgende drei Bedingungen erfüllt sind (alle drei):
  1. Das globale Pullup Disable Bit (PUD in MCUCR) ist nicht gesetzt.
  2. Das lokale Data Direction Bit (DDxn) ist nicht gesetzt. (Dann ist der Ausgangstreiber inaktiv)
  3. Das lokale PORT Latch Bit (PORTxn) ist gesetzt.
Nachtrag:
Abgesehen von dem einen (globalen) Pullup Disable Bit in MCUCR (welches die Pullups aller Beine des Controllers gemeinsam, unabhängig von den hier genannten Bits, abschaltet (ein Override eben)) gibt es also für jedes Bein drei Bits, mit denen es sich verwalten läßt.
Die AVR sind 8Bit-Controller, alle I/O-Register sind also 8 Bit breit. Dementsprechend werden immer bis zu acht Beine zu einem "Port" zusammengefaßt (nein, das hat nichts mit dem gleichnamigen Register zu tun - ungünstige Namenswahl) - man könnte auch Gruppe sagen. Die Gruppen werden duch Buchstaben gekennzeichnet - A, B usw.
Der ATtiny2313A hat zB acht Beine, die als PortB (Gruppe B) zusammengefaßt sind. Für die ganze Gruppe gibt es also je ein Data Direction Register (DDRB), ein Port Input Register (PINB) und ein Port Latch Register (PORTB).
Jedes dieser drei Register verfügt über acht Bit, eins für jedes Bein.
In den obigen Darstellungen entspricht dann zB "DDxn" dem Bit "n" im Data Direction Register von Portx, also DDRx.

Da sich alle Bits einer "Gruppe" an einem Register befinden, kann man also gleichzeitig alle Pegel oder die Datenrichtung der entsprechenden Beine festlegen, da der Zugriff auf das Register die Gruppe als ganzes betrifft. Oder gleichzeitig die tatsächlichen Pegel aller Beine einer Gruppe lesen lassen.

Achso: Die ganze Erklärung betrifft übrigens nur die normale Funktion der Beine - werden alternative Hardware-Funktionen aktiviert (UART, SPI, TWI, PWM usw) können Die Verbindungen zwischen dem jeweiligen Bein und den ansteuernden Bits durch Overrides außer Kraft gesetzt (abgekoppelt) werden. Näheres dazu findet sich unter "Alternate Functions" in den Datenblättern...
 
Zuletzt bearbeitet:
Wertungen: TommyB und Dirk

Hero_123

Mitglied
17 Sep 2010
62
2
8
Sprachen
C
Hallo LotadaC

Klasse - das ist eine tolle Erklärung :good3:

mfg
Hero_123
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.090
57
48
Hennigsdorf
Sprachen
BascomAVR, Assembler
Ok, was ist nun mit der anderen Architektur (die bei den TPI-ATtinies aber eben auch dem ATtiny441/841 und dem ATtiny1634 eingesetzt ist)?
Also (PUExn-Ansteuerung).

Der Weg vom Bein über diese Sleep-Abschaltung, den Schmitt-Trigger, den Synchronizer zum PINxn-Bit und von da zum Bus ist identisch.
Die Aktivierung des Ausgangstreibers durch das DDxn-Bit (aus dem Bus) ist auch genau so wie oben.
Ach das Festlegen des Bein-Pegels (bei aktiviertem Treiber) durch das PORTxn-Bit ist unverändert.

Weggefallen ist das AND-Gatter (6B), stattdessen gibt es jetzt ein viertes Bit (PUExn - (6C)), welches den Pullup-Aktivierungs-Transistor(6A) direkt ansteuert (also eben nicht mehr von DDR und PORT abhängig).


7998

Dieses PUE-Bit ist natürlich entsprechend des obigen Nachtrages auch als 8-Bit-Register realisiert - es lassen sich also alle Pullups einer "Gruppe" gleichzeitig manipulieren.

Da das PUE-Register unabhängig vom DDR- und PORT-Register ist, kann also der Pullup aktiviert werden (PUExn=1), während das Bein "Ausgang" ist (DDxn=1). Ist der gesetzte Pegel high (PORTxn=1), liegt der Pullup parallel zum Ausgangstreiber auf Vcc - ist der Pegel aber low (PORTxn=0), schaltet der Ausgangstreiber auf Gnd (klar), der Pullup aber auf Vcc - es fließt also Strom von Vcc intern über den Pullup und durch den Ausgangstreiber nach Gnd.
Der wird natürlich durch den Pullup begrenzt (der AVR verträgt das also) - trotzdem ist so eine Chip-Heizung laut Datenblatt nicht empfohlen.

Wahrscheinlich eher nur für hardwarenahe Programmierer (Team Bitschubse) relevant:
PORT-, PIN- und DDR-Register befinden sich fast immer im 0x1F-Adressbereich - es kann also durch IN und OUT schnell zugegriffen werden (Standard I/O). Insbesondere sind die Register-Bits sogar "direct Bit accessible" (ohne Umweg über die Rechenregister).
Das PUE-Register hingegen befindet sich (im allgemeinen ?) im "Extended I/O Space", muß also wie SRAM gelesen/-schrieben werden.

(@me - memoriere: In einem ATtiny841 die Pullup-Heizung mal durch den internen "Temperatursensor" ausmessen lassen! (ein Kelvin Auflösung vs. geringe Heizleistung...)
 
Zuletzt bearbeitet:

dino03

Aktives Mitglied
27 Okt 2008
6.701
14
38
Sprachen
BascomAVR, Assembler
Hi LotadaC,

(@me - memoriere: In einem ATtiny841 die Pullup-Heizung mal durch den internen "Temperatursensor" ausmessen lassen! (ein Kelvin Auflösung vs. geringe Heizleistung...)
wenn der PullUp noch wie bei den alten Chips bei etwa 50k liegt (war glaube ich der Wert), dann wird da nicht viel heizen.
Für LowEnergy oder Geräten, die lange mit ner Batterie laufen sollen, ist das aber natürlich kontraproduktiv :)

Spass: Evtl könnte man dadurch ja für Outdoorgeräte ne "Kondenswasserverdampfung" mit bauen ;) Oder die interne Spannungsquelle für den ADC temepraturstabilisieren (Referenz-Ofen).

Stromquellen wie bei den I2C-Portbausteinen werden die da wohl nicht verbaut haben.

Gruß
Dino
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.090
57
48
Hennigsdorf
Sprachen
BascomAVR, Assembler
:offtopic:
bei etwa 50k liegt
Laut Datenblatt etwa 30..60kΩ, ich hätte also mit 45kΩ gerechnet (Daumen_1). Als Versorgungsspannung ferner 'n ∆U von 5V (Daumen_2, was in den internen FETs abfällt, heizt ja auch im Chip), dann wäre ich nach P=U²/R bei 0,5Periode5 mW.

Der Tiny841 hat 12 I/Os, Reset und TxD weggelassen blieben 10. Mit 10 Pullups wären wir also mit 5,55Periode5 mW Heizleistung dabei. Wie war das jetzt mit (Milli-)Wattsekunden und ∆Kelvin? Meine Physik ist inzwischen recht eingerostet, fürchte ich...

Zurück zum Thema:
Wie sieht das jetzt bei den X-Core-ATtinies aus? Ich hatte ja vermutet, daß es auch da mit PUExn wäre. Hier mal ein Bild aus dem Datenblatt des ATtiny214/414:
7999
Als erstes fällt auf, daß irgendjemand auf die wahnsinnig innovative Idee gekommen ist, die Darstellung horizontal zu spiegeln... na meinetwegen...
Der Datenbus (und die Ansteuerung der DQ-Latches/Register-Bits) ist nicht mehr dargestellt, aber den gibt's natürlich genauso.
Daß es die Override-Multiplexer (hier schwarz) auch in den anderen Architekturen gibt, hatte ich bereits gesagt.
Was ist anders?
  • PINxn heißt jetzt INn
  • DDRxn heißt jetzt DIRn
  • PORTxn heißt jetzt OUTn
  • PUExn heißt Pullup enable (dazu später mehr)
  • die beiden, von mir grün eingekreisten XOR-Gatter
Wie bei der PUExn-Architektur kann ich also den tatsächlichen Bein-Pegel lesen (jetzt aus dem IN-Register), den Ausgangstreiber aktivieren (jetzt über das DIR-Register), und (bei aktiviertem Treiber) den Pegel des Beines festlegen (mit dem OUT-Register).

IN, OUT und DIR sind auch hier drei 8-Bit-Register, mit je einem Bit für ein Bein - es sind acht Beine zu einer Gruppe zusammengefaßt.
Das Pullup enable hingegen nicht.
Es gibt jetzt für jedes Bein ein eigenes Pin n Control Register (PINnCTRL), welches unter anderen ein PULLUPEN-Bit enthält. Sollen also zB die Pullups aller Beine einer Gruppe aktiviert werden, müssen jetzt nacheinander alle acht PINnCTRL-Register einzeln beschrieben werden (natürlich unter Berücksichtigung der anderen Bits dieser Register).

Und die XOR-Gatter?
Wenn das "Invert Enable"-Signal low ist, verhalten sich die Gatter als 1-Gatter (Treiber) - das OUT-Bit landet unverändert auf dem Bein, der Bein-Pegel unverändert im IN-Bit.
Ist das Signal aber high, wird das jeweilige Bit mit 1 verXORt, also invertiert.
Genau das sagt ja "Invert Enable"-
Und wo kommt dieses Signal her?
Auch aus dem PINnCTRL-Register, es kann also für jedes Bein getrennt festgelegt werden. Außerdem wird dort festgelegt, wie sich das Bein als externer Interrupt verhalten soll (jedes Bein kann auf steigende, fallende, jede Flanke oder auf low-Level triggern, alle Beine einer Gruppe landen in derselben ISR - ähnlich den PCINTs)).

Jetzt wieder was für hardwarenahe Programmierer:
Den OUT- und DIR-Registern stehen noch je ein -SET, -CLEAR und -TOGGLE-Register zur Seite. Bei sonst nötigen Read-Modify-Write-Manipulationen entfällt das Read, das Modify wird ggf zum LDI. Diese Register sind quasi Writeonly (gesetzte Bits setzen/löschen/toggeln die korrespondierenden Bits in OUT/DIR) - liest man die Register, erhält man den Inhalt von OUT/DIR.
Wird das IN-Register beschrieben, toggeln gesetzte Bits die Bits im OUT-Register. (Pin-Toggling).

Alle genannten Register befinden sich im Extended I/O-Space, Zugriffe entsprechen also SRAM-Zugriffen. IN, OUT und DIR (und das Interrupt-Flag-Register) sind allerdings zusätzlich in den konventionellen I/O remapped (Virtual Port), sogar in den Adressbereich, und dort sind sie wie gehabt mit den üblichen Instruktionen erreichbar und auch direct bit accessible.
Überhaupt ist bei den X-Cores der konventionelle I/O recht dünn belegt, hier mal vom Tiny212/214:
  • 0x0000 - VPORTA - 4 Register (remapped DIR, IN, OUT und Flags - 0x0000..0x0003)
  • 0x001C - GPIO - 4 GPIO-Register (0x001C..0x001F) <---Ende des direct bit accessible Space
  • 0x0030 - CPU - 4 Register (CCP, 2 x Stackpointer, SREG - 0x0034, 0x003D..3E, 0x003F) <--- Ende conventional I/O Space
Ok, zwischen 0x0003 und 0x001C werden bei größeren Controllern weitere virtuelle Ports landen (PORTB..PORTG ? ).
Zwischen GPIO- und CPU-Block klafft eine 16-Register-Lücke, im CPU-Block scheinen 12 Register ungenutzt.

Das scheint auch bei größeren X-Cores so zu sein (mehr virtuelle Ports oben, klar). Auf der anderen Seite vermute ich "irgendwo versteckte" Register des PTC - der hat nämlich scheinbar weder Register noch Interrupt-Einsprungadressen.
"Versteckt" natürlich nicht wirklich - es werden eben irgendwelche, nicht weiter dokumentierte Adressen verwendet. Möglicherweise im conventional, möglicherweise im Extended I/O.

nochmal :offtopic:
Ich lenke Deinen Blick mal dezent auf den ATtiny87/167 (allerdings nur 100µA)...
 
Zuletzt bearbeitet:

Janiiix3

Aktives Mitglied
28 Sep 2013
1.292
10
38
Hannover
Sprachen
C, C#
Möglicherweise werden einige neuere AVR dann auch diese Bein-Architektur aufweisen...
Bei der "XMEGA" Baureihe, hat ATMEL auch einiges erneuert in dieser Hinsicht.
Ähnelt schon fast deinem "Tiny".
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.090
57
48
Hennigsdorf
Sprachen
BascomAVR, Assembler
Ähnelt schon fast deinem "Tiny".
Ich bin vor fast exakt 5 Jahren über diese Architektur (PUExn) im Tiny841 gestolpert, und habe darauf diesen Thread gestartet.
Später bin ich dann auf die TPI-Tinies (erst den Tiny4/5/9/10, danach die anderen) gestoßen, die diese Architektur konsequent umsetzt.
Tiny441/841 und Tiny1634 sind im wesentlichen klassische Tinies (ISP over SPI), besitzen aber einige, für diese "Klasse" untypische Module. Unter anderem eben die "Bein-Architektur". Deswegen bezeichne ich(!) sie als Hybrid.
Meiner(!!) Meinung nach ist die Entwicklung der TPI-Tinies abgeschlossen, auch bei den klassischen Tinies wird wahrscheinlich nichts neues mehr kommen...

Bei den X-Core-Tinies ist die Sache recht eindeutig: Das sind quasi Tinies mit (einigen und teilweise stark reduzierten) XMega-Perepheriemodulen. Insofern ist die von Dir erkannte Ähnlichkeit logisch - aber eben andersrum. Die X-Tinies ähneln den X-Megas.
Unter anderem auch in der "Bein-Architektur" - nicht "PUExn", sondern "PULLUPEN".
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)