MCP23017 — расширитель портов GPIO (Arduino)

MCP23017 —  расширитель портов GPIO, который позволяет управлять до 16 цифровыми устройствами через один интерфейс I2C. Он имеет два порта по 8 GPIO каждый, что позволяет контролировать 16 цифровых сигналов с помощью всего двух выводов микросхемы.

Основные параметры MCP23017:

— Напряжение питания: 1,8 В — 5,5 В
— Количество портов ввода-вывода: 16 (2 порта по 8 GPIO)
— Интерфейс связи: I2C
— Максимальный ток, выдаваемый на каждый порт: 25 мА
— Возможность программной настройки каждого GPIO на вход или выход, а также на подтягивание к питанию или земле.

MCP23017 может использоваться во многих приложениях, включая управление светодиодами, кнопками, дисплеями, реле, сенсорами и т.д.

Кроме того, MCP23017 имеет возможность настройки прерываний, что позволяет микроконтроллеру не постоянно опрашивать состояние портов, а получать уведомления только в случае изменения состояния определенных портов.

MCP23017 имеет два регистра конфигурации (IODIRA и IODIRB), которые позволяют настроить каждый порт на вход или выход. Кроме того, есть два регистра подтягивающих резисторов (GPPUA и GPPUB), которые позволяют подключить подтягивающие резисторы к каждому порту, что может быть полезно, например, при использовании кнопок.

MCP23017 также имеет регистры для чтения и записи состояния каждого порта (GPIOA и GPIOB), а также регистры для управления состоянием портов (OLATA и OLATB), что позволяет микроконтроллеру устанавливать или считывать состояние портов с помощью I2C интерфейса.

Кроме того, MCP23017 имеет встроенную защиту от короткого замыкания и перегрузки, что позволяет увеличить надежность и безопасность системы.

Возможности MCP23017 можно расширить, используя несколько микросхем вместе. Например, можно подключить несколько MCP23017 к одному интерфейсу I2C и управлять до 128 GPIO (8 микросхем по 16 GPIO). При этом каждая микросхема должна иметь уникальный адрес, который можно настроить с помощью специальных пинов на микросхеме.

MCP23017 может иметь до 8 уникальных адресов, которые можно настроить с помощью пинов A0, A1 и A2 на микросхеме. В таблице приведены возможные адреса для MCP23017:

A2 A1 A0      Адрес
0   0   0          0x20
0   0   1          0x21
0   1   0          0x22
0   1   1          0x23
1   0   0          0x24
1   0   1          0x25
1   1   0          0x26
1   1   1          0x27

В целом, MCP23017 является удобным и мощным расширителем портов, который может быть использован во многих различных проектах для управления цифровыми устройствами.

Расширитель портов MCP23017 можно приобрести в виде готового модуля cjmcu-2317:

 

Для тестирования модуля необходимо замкнуть контакты А0 А1 А2 на VCC или GND для получения нужного Вам I2C адреса.

При замыкании контактов А0 А1 А2 на GND и загрузив сканер I2C портов (скетч можно найти в примерах Arduino IDE), в мониторе можно увидеть установленный I2C адрес:

Для удобства использования расширителя портов можно воспользоваться библиотекой — Adafruit-MCP23017-Arduino-Library-master, дополнительно Вам может понадобится библиотека — Adafruit_BusIO-master.

При обращении к пинам расширителя портов в Arduino IDE используйте таблицу:

ИМС MCP23017 Модуль Pin Arduino IDE
21 A0 0
22 A1 1
23 A2 2
24 A3 3
25 A4 4
26 A5 5
27 A6 6
28 A7 7
1 B0 8
2 B1 9
3 B2 10
4 B3 11
5 B4 12
6 B5 13
7 B6 14
8 B7 15

Примеры использования

  • Blink (Мигание светодиодом)

Подключите светодиод в пину А0 (через резистор 100 Ом). После загрузки скетча светодиод начнет мигать с периодом 1 секунда.

#define LED_PIN    0 // LED PIN A0

#include <Adafruit_MCP23X17.h>
Adafruit_MCP23X17 mcp;

void setup() {
  Serial.begin(9600);
  mcp.begin_I2C(0x20);
  mcp.pinMode(LED_PIN, OUTPUT);
}

void loop() {
  mcp.digitalWrite(LED_PIN, HIGH);
  delay(500);
  mcp.digitalWrite(LED_PIN, LOW);
  delay(500);
}
  • Read/Write GPIO

Ниже показан демонстрационный скетч, который демонстрирует работу чтения и записи GPIO входа/выхода. Для демонстрации работы скетча Вам необходимо подключить светодиод к выходу А0 (через сопротивление 100 Ом) и кнопку (нажатие — замыкание на GND) ко входу А1.

При нажатии на кнопку светодиод будет загораться и гаснуть при повторном нажатии на кнопку.

#define LED_PIN    0 // LED PIN A0
#define BUTTON_PIN 1 // BUTTON PIN A1

#include <Adafruit_MCP23X17.h>
Adafruit_MCP23X17 mcp;
bool ledState = false;

void setup() {
  Serial.begin(9600);
  mcp.begin_I2C(0x20);
  mcp.pinMode(LED_PIN, OUTPUT);
  mcp.pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() {
  if (mcp.digitalRead(BUTTON_PIN) == LOW){
    ledState = !ledState;
  mcp.digitalWrite(LED_PIN, ledState);
  while (mcp.digitalRead(BUTTON_PIN) == LOW); 
  delay(200);
  }
}
  • Interrupt

В ИМС MCP23017 имеются 2 выхода Interrupt (INTA/INTB), отдельно для каждого порта А и В для вывода сигнала прерывания. В данном примере при нажатии кнопку которая подключена ко входу А4, происходит прерывание, на выходе INTА появляется сигнал прерывания. Вывод INTА подключен ко входу D7 платы Arduino для считывания сигнала прерывания.

При нажатии на кнопку происходит прерывание, сигнал прерывания поступает на вход D7 и в мониторе порта появляется сообщение о прерывании с определением номера пина источника прерывания.

Определение номера пина источника прерывания происходит при помощи функции mcp.getLastInterruptPin().

#define INT_PIN    7 // вывод микроконтроллера, подключенный к INTA/B
#define BUTTON_PIN 4 // BUTTON PIN A4

#include <Adafruit_MCP23X17.h>
Adafruit_MCP23X17 mcp;
bool ledState = false;

void setup() {
  Serial.begin(9600);
  mcp.begin_I2C(0x20);
  pinMode(INT_PIN, INPUT);
  mcp.setupInterrupts(true, false, LOW);
  // INTA/B будет НИЗКИМ при наступлении прерывания
  // MCP23XXX поддерживает следующие режимы прерывания:
  //    * CHANGE - прерывание происходит, если вывод переходит в противоположное состояние
  //    * НИЗКИЙ - прерывание происходит, когда состояние вывода LOW
  //    * HIGH - прерывание происходит, когда состояние вывода HIGH
  mcp.pinMode(BUTTON_PIN, INPUT_PULLUP);
  mcp.setupInterruptPin(BUTTON_PIN, LOW);
  // разрешить прерывание на button_pin
}

void loop() {
  if (!digitalRead(INT_PIN)) {
    Serial.print("Interrupt detected on pin: ");
    Serial.println(mcp.getLastInterruptPin());
    delay(250);
    mcp.clearInterrupts();  // clear
  }
}

 

Добавить комментарий

Войти с помощью: