Verständnisproblem MCP23S17 Hardware Adresse

OP #6621266
Lesenswert?

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
OP #6621386
Lesenswert?

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
#6621394
Lesenswert?

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
OP #6621935
Lesenswert?

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
#6622044
Lesenswert?

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
OP #6622074
Lesenswert?

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
#6622079
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren