Ich habe vier MCP23S17 an einem Atmega32U2.
MISO, MOSI SCK und !CS sind alle gemeinsam auf einem Bus.
Die Adresspins sind unterschiedlich beschaltet und so lassen sich die
ICs einzeln ansprechen.
Mein Problem:
Das DB sagt, dass nach Reset IOCON.HAEN=0 ist und somit die Adresspins
NICHT aktiv sind, warum funktioniert das einzelne Ansprechen aber?
Beitrag "MCP23S17 kaskadieren" kommt auch zum
Ergebnis, dass das nicht funktionieren sollte.
Matthias
Schau mal ins Errata:
http://ww1.microchip.com/downloads/en/DeviceDoc/80311a.pdf
Wenn A2 high ist, scheint das das HAEN bit zu bypassen, dann wird die
Adresse auf jeden Fall verglichen.
Viele Grüße
Jochen
Jochen S. schrieb:
> http://ww1.microchip.com/downloads/en/DeviceDoc/80311a.pdf
>
> Wenn A2 high ist, scheint das das HAEN bit zu bypassen, dann wird die
> Adresse auf jeden Fall verglichen.
Schonmal interessant, kann aber hier nicht die Ursache sein, bei allen 4
liegt A2 auf GND, die haben die Adressen 0..3. Seltsam.
Wobei, wenn man es logisch überlegt: wenn das wie im DB beschrieben
wäre, dann müsste man immer für jeden IC ein !CS spendieren und diese
Funktion wäre sinnlos.
Matthias
Wieso sinnlos? Du könntest mit einem Kommando an alle gleichzeitig das
HAEN-Bit zu Beginn auf 1 setzen. Ab dem nächsten Zugriff wären sie dann
per Adresse unterscheidbar. Kollision auf MISO wäre dabei auch nicht zu
erwarten, weil beim Nur-Schreiben SO auf High-Z liegt.
Da die Bausteine die Pins für die I2C-Variante eh haben, ist es nur
clever, die auch für SPI zu benutzen, um die Anzahl möglicher
CS-Leitungen zu reduzieren.
Gruß
Jochen
Jochen S. schrieb:
> Wieso sinnlos? Du könntest mit einem Kommando an alle gleichzeitig das
> HAEN-Bit zu Beginn auf 1 setzen. Ab dem nächsten Zugriff wären sie dann
> per Adresse unterscheidbar.
Das klingt logisch, vermutlich passiert auch genau das. Ich werde
testen.
Matthias
Ja, das ist die Erklärung, alle werden gemeinsam beschrieben.
1 | /* MCP_0..MCP_7 --> MCP23S17 mit Hardwareadresse 0..7 */
| 2 | /* nach Reset werden MCP_0..MCP_3 gemeinsam angesprochen, weil HAEN=0 ist */
| 3 | mcp_write_register( MCP_0, MCP_IOCON, HAEN | MIRROR );
|
ist also gleichwertig mit: 1 | mcp_write_register( MCP_0, MCP_IOCON, HAEN | MIRROR );
| 2 | mcp_write_register( MCP_1, MCP_IOCON, HAEN | MIRROR );
| 3 | mcp_write_register( MCP_2, MCP_IOCON, HAEN | MIRROR );
| 4 | mcp_write_register( MCP_3, MCP_IOCON, HAEN | MIRROR );
|
Wenn MCP_4..MCP_7 (auch) existieren, dann muss es nach dem Errata
heissen: 1 | /* nach Reset werden MCP_0..MCP_7 gemeinsam angesprochen, weil HAEN=0 ist */
| 2 | /* MCP_4 muss es wegen http://ww1.microchip.com/downloads/en/DeviceDoc/80311a.pdf sein */
| 3 | mcp_write_register( MCP_4, MCP_IOCON, HAEN | MIRROR );
|
Wieder was gelernt.
Matthias
Das freut mich!
Ja, wenn acht Teilnehmer da sind, musst du zwei Zugriffe machen:
1 | mcp_write_register( MCP_0, MCP_IOCON, HAEN | MIRROR );
|
für einen gemeinsamen Zugriff auf alle Teilnehmer, bei denen A2 = 0 ist
und
1 | mcp_write_register( MCP_4, MCP_IOCON, HAEN | MIRROR );
|
für einen gemeinsamen Zugriff auf alle Teilnehmer, bei denen A2 = 1 ist.
Ab da kannst du sie über die Adressen 0 bis 7 unterscheiden.
Viele Grüße
Jochen
Jochen S. schrieb:
1 | mcp_write_register( MCP_4, MCP_IOCON, HAEN | MIRROR );
|
> für einen gemeinsamen Zugriff auf alle Teilnehmer, bei denen A2 = 1 ist.
ist klar.
Bei denen mit A2=0 funktioniert ja das Ignorieren der Adresspins, die
sollten eigentlich auch davon erfasst werden.
Ich versuche das mal nachzustellen, SSOP passt leider schlecht auf ein
Steckbrett. :-(
Matthias
Stimmt, cool! So weit hab ich gar nicht gedacht. Einmal an die "4"
gesendet müsste man alle Busteilnehmer erreichen.
Hätte man zur Klarstellung und als How-to auch ruhig so ins Errata
reinschreiben können, statt es so umständlich zu verklausulieren und bei
Workaround "None" anzugeben.
Viele Grüße
Jochen
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|