Wenn man viele I/O-Ports mit einem Microcontroller ansteuern möchte, kann man Schieberegister verwenden, wie das 74HC595. Diese Lösung ist relativ günstig, erfordert aber mindestens drei Leitungen zur Ansteuerung und funktioniert nur in eine Richtung. Will man auch Daten einlesen, ist ein anderer Baustein wie der 74HC165 erforderlich und damit weitere Leitungen, wenn das parallel erfolgen soll.
Eine deutlich flexiblere Lösung ist der Port-Expander MCP23017. Dieser Chip wird über I2C angesteuert und bietet 16 Ports, die einzeln als Ein- oder Ausgang konfiguriert werden können.
Es gibt auch die Variante MCP23008 mit weniger Ports und die Variante MCP23S17 mit SPI-Schnittstelle statt I2C.
Anschlussbelegung
Die Varianten in einem DIP28-Gehäuse (MCP23017, MCP23S17) sind wie folgt belegt:
Pin | Bezeichnung | Beschreibung | Pin | Bezeichnung | Beschreibung |
---|---|---|---|---|---|
1 | GPB0 | I/O-Port 8 | 28 | GPA7 | I/O-Port 7 |
2 | GPB1 | I/O-Port 9 | 27 | GPA6 | I/O-Port 6 |
3 | GPB2 | I/O-Port 10 | 26 | GPA5 | I/O-Port 5 |
4 | GPB3 | I/O-Port 11 | 25 | GPA4 | I/O-Port 4 |
5 | GPB4 | I/O-Port 12 | 24 | GPA3 | I/O-Port 3 |
6 | GPB5 | I/O-Port 13 | 23 | GPA2 | I/O-Port 2 |
7 | GPB6 | I/O-Port 14 | 22 | GPA1 | I/O-Port 1 |
8 | GPB7 | I/O-Port 15 | 21 | GPA0 | I/O-Port 0 |
9 | VDD | +1,8 V bis +5,5 V | 20 | INTA | |
10 | VSS | GND | 19 | INTB | |
11 | N.C. / CS | SPI | 18 | RESET | |
12 | SCL / SCK | I2C / SPI | 17 | A2 | I2C-Adresse |
13 | SDA / SI | I2C / SPI | 16 | A1 | I2C-Adresse |
14 | N.C. / SO | SPI | 15 | A0 | I2C-Adresse |
VDD, VSS
Die Spannungsversorgung sollte zwischen 1,8 und 5,5 Volt liegen. Damit ist auch die Nutzung mit einem Microcontroller, der mit 3,3 Volt arbeitet, kein Problem.
SCL, SDA, CS, SCK, SI, SO
Die Varianten mit I2C (MCP23017, MCP23008) werden die SCL und SDA angesteuert. Für eine stabile Verbindung ist es sinnvoll, SCL und SDA jeweils mit 4,7 kΩ an VSS zu terminieren.
Für SPI (MCP23S17, MCP23S08) werden CS, SCK, SI und SO verwendet.
GPA0-GPA7, GPB0-GPB7
Diese Pins stellen die 16 I/O-Ports dar. Jeder Port kann individuell als Ein- oder Ausgang konfiguriert werden. Die Ports sind in zwei Gruppen A und B zusammengefasst. Wenn man die Ports konfiguriert, kann man das auch gruppenweise machen.
Bei der Nutzung als Eingang kann optional für jeden Port auch ein 100 kΩ-Pull-Up-Widerstand aktiviert werden.
RESET
Über diesen Eingang kann der Chip zurückgesetzt werden. Dazu wird der Pin kurzzeitig mit Masse (VSS) verbunden. Für den regulären Betrieb kann man diesen Pin auch dauerhaft mit VDD verbinden.
INTA, INTB
Diese Eingänge stellen die Interrupt-Eingänge dar. Die Polarität kann konfiguriert werden und beide Eingäng können zusammengeschaltet werden.
A0-A2
Die Eingänge A0-A2 legen die I2C-Adresse wie folgt fest:
A0 | A1 | A2 | I2C-Adresse |
---|---|---|---|
0 | 0 | 0 | 0x20 (32) |
1 | 0 | 0 | 0x21 (33) |
0 | 1 | 0 | 0x22 (34) |
1 | 1 | 0 | 0x23 (35) |
0 | 0 | 1 | 0x24 (36) |
1 | 0 | 1 | 0x25 (37) |
0 | 1 | 1 | 0x26 (38) |
1 | 1 | 1 | 0x27 (39) |
Dadurch können insgesamt bis zu 8 Port-Expander gleichzeitig betrieben werden und zusammen 128 I/O-Ports bereitstellen.
Ansteuerung mit Adafruit_MCP23X17
Die genaue des MCP23017 Funktion kann man dem Datenblatt entnehmen. Man muss sich aber nicht die Arbeit machen, eigene Funktionen zur Ansteuerung zu entwickeln. Es gibt von Adafruit eine fertige MCP23017-Bibliothek, die man für zahlreiche Microcontroller nutzen kann und die auch für MCP23017, MCP23S17, MCP23008 und MCP23S08 nutzbar ist. Für die Ansteuerung von HD44780-kompatiblen LC-Displays über einen MCP23017 kann man LiquidCrystalIO verwenden. Vom selben Autor stammt auch IoAbstraction für die Verbindung zu unterschiedlicher Peripherie. Diese Bibliotheken findet man auch in PlatformIO, wenn man nach „mcp23017“ sucht.
Als Minimalbeispiel nachfolgend die Ansteuerung von 4 LEDs an GPA0-GPA3 als „Lauflicht“:
#include <Arduino.h> #include <Wire.h> #include <Adafruit_MCP23X17.h> Adafruit_MCP23X17 mcp; void setup() { if (!mcp.begin_I2C(0x20)) { while (1); } for (int port=0; port<4; port++) { mcp.pinMode(port, OUTPUT); mcp.digitalWrite(port, LOW); } } void loop() { for (int port=0; port<4; port++) { mcp.digitalWrite(port, HIGH); delay(500); mcp.digitalWrite(port, LOW); } }
Der Aufbau mit einem D1 mini auf einem Breadboard:
Die I2C-Verbindung zum MCP23017 erfolgt über die Anschlüsse D1 und D2 des D1 Mini wie folgt: D1 mit SCK und D2 mit SDA. Die I2C-Verbindung wird außerdem über zwei Widerstände mit 4,7 kΩ gegen VSS terminiert. Die Adresseinstellung des MCP23017 wurde mit A0-A2 auf 0x20 gestellt.
Die Stromversorgung des MCP23017 erfolgt über die Anschlüsse 5V und G (GND) des D1 Mini. Die vier LEDs sind jeweils über 1 kΩ mit GND verbunden.