Расширитель портов I2C

Как работают переключатели и их виды

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

Расширитель портов I2C: общие сведения

Если рассматривать в общем, то расширитель портов увеличивает общее количество доступный портов ввода-вывода. Управляется такая микросхема через интерфейсы I2C, SPI.

ВАЖНО! Такие микросхемы увеличивают цифровые порты ввода-вывода.

Расширитель портов PCA9555

Данная микросхема управляется через интерфейс I2C. Доступно 16 бит или 16 дополнительных выводов. На рисунке ниже представлена подробная блок схема микросхемы:

Расширитель портов I2C PCA9555

Контакты А0, А1, А2 задают адрес устройства, а это значит, что в одном устройстве можно использовать до 8 расширителей портов PCA9555. Согласитесь, внушительная получается цифра.

Контакт INT — прерывание по изменению значения на контактах. Прерывание срабатывает если контакты настроены как вход.
ВАЖНО! Прерывание INT срабатывает по любому изменению на контактах. Например: если у вас подключена через расширитель кнопка, то Прерывание будет срабатывать как при нажатии так и при отпускании кнопки.

Регистры PCA9555

Микросхема имеет 8 регистров для настройки и управления портами. они представлены в таблице ниже:

КОДИмяОписание
0Input port 0Содержит значения порта 0, настроенного на вход
1Input port 1Содержит значения порта 1, настроенного на вход
2Output port 0Содержит значения порта 0, настроенного на выход. Можно читать и записывать.
3Output port 1Содержит значения порта 1, настроенного на выход. Можно читать и записывать.
4Polarity Inversion port 0Меняет полярность сигнала на контактах порта 0
5Polarity Inversion port 1Меняет полярность сигнала на контактах порта 1
6Configuration port 0Настраивает контакты порта 0 на вход или выход. 0-вход, 1- выход.
7Configuration port 1Настраивает контакты порта 1 на вход или выход. 0-вход, 1- выход.

Библиотека PCA9555 для STM32

Библиотека написана без использования регистра смены полярности сигнала. Так же читается состояние портов настроенных как вход. Состояние портов настроенных как выход, храниться в переменной без проверки чтением.

ВАЖНО! Для конфигурации, или чтения можно указать адрес первого или второго порта, а данные отправить на 2 порта сразу. Они идут парами, по этому Записав данные в нулевой порт, следующие будут записаны в первый порт одного регистра.

#include "stm32f4xx_hal.h"

// Адреса наших устройств A0-A2
#define PCA9555_ADR20   0x20
#define PCA9555_ADR21   0x21
#define PCA9555_ADR22   0x22
#define PCA9555_ADR23   0x23
#define PCA9555_ADR24   0x24
#define PCA9555_ADR25   0x25
#define PCA9555_ADR26   0x26
#define PCA9555_ADR27   0x27


//Команды конфигурации
#define PCA9555_INPUT_PORT_0                  0
#define PCA9555_INPUT_PORT_1                  1
#define PCA9555_OUTPUT_PORT_0                 2
#define PCA9555_OUTPUT_PORT_1                 3
#define PCA9555_POLARITY_INVERSION_PORT_0     4
#define PCA9555_POLARITY_INVERSION_PORT_1     5
#define PCA9555_CONFIG_PORT_0                 6
#define PCA9555_CONFIG_PORT_1                 7


HAL_StatusTypeDef  Transmit2PCA9555(I2C_HandleTypeDef hi2c, uint8_t addr_dev, uint8_t registr_addr, uint16_t data_write2registr);
HAL_StatusTypeDef Transmit2PCA9555_R1(I2C_HandleTypeDef hic, uint8_t addr_dev, uint8_t registr_addr, uint8_t data_write2registr);
HAL_StatusTypeDef Transmit2PCA9555_R2(I2C_HandleTypeDef hic, uint8_t addr_dev, uint8_t registr_addr, uint8_t data_write2registr);
uint16_t Recieve_fromPCA9555(I2C_HandleTypeDef hi2c, uint8_t addr_dev, uint8_t registr_addr);
uint16_t GetPinout(I2C_HandleTypeDef hi2c, uint8_t addr_dev);
uint8_t PCA9555_InitPort(I2C_HandleTypeDef hic, uint16_t portDir, uint16_t portInit, uint8_t adr);
#include "PCA9555.h"

HAL_StatusTypeDef Transmit2PCA9555(I2C_HandleTypeDef hic, uint8_t addr_dev, uint8_t registr_addr, uint16_t data_write2registr)
{
	HAL_StatusTypeDef stat;
	uint8_t mas_data[3];
	mas_data[0] = registr_addr;
	mas_data[1] =  data_write2registr;
	mas_data[2] = (data_write2registr>>8)&0xFF;
	addr_dev = addr_dev << 1 ;
	stat = HAL_I2C_Master_Transmit(&hic, addr_dev, mas_data,3,50);
	return stat;
}

HAL_StatusTypeDef Transmit2PCA9555_R1(I2C_HandleTypeDef hic, uint8_t addr_dev, uint8_t registr_addr, uint8_t data_write2registr)
{
	HAL_StatusTypeDef stat;
	uint8_t mas_data[3];
	mas_data[0] = registr_addr;
	mas_data[1] =  data_write2registr;
	addr_dev = addr_dev << 1 ;
	stat = HAL_I2C_Master_Transmit(&hic, addr_dev, mas_data,2,50);
	return stat;
}

HAL_StatusTypeDef Transmit2PCA9555_R2(I2C_HandleTypeDef hic, uint8_t addr_dev, uint8_t registr_addr, uint8_t data_write2registr)
{
	HAL_StatusTypeDef stat;
	uint8_t mas_data[3];
	mas_data[0] = registr_addr;
	mas_data[1] =  data_write2registr;
	addr_dev = addr_dev << 1 ;
	stat = HAL_I2C_Master_Transmit(&hic, addr_dev, mas_data[0],1,50);
	stat = HAL_I2C_Master_Transmit(&hic, addr_dev, mas_data[1],1,50);
	return stat;
}
uint16_t Recieve_fromPCA9555(I2C_HandleTypeDef hic, uint8_t addr_dev, uint8_t registr_addr)
{
	uint8_t incoming[2];
	uint16_t port = 0;
	HAL_StatusTypeDef stat;
	stat = HAL_I2C_Master_Transmit(&hic,addr_dev<<1, &registr_addr,1,50);
	stat = HAL_I2C_Master_Receive(&hic,(addr_dev<<1) | 0x01,(uint8_t*)&incoming,2,50);
	port = (incoming[1] <<8) | incoming[0];
	if (stat == HAL_ERROR) return 0;
	return port;
}

uint16_t GetPinout(I2C_HandleTypeDef hic, uint8_t addr_dev)
{
	uint16_t pinout = 0;
	pinout = Recieve_fromPCA9555(hic,  addr_dev,  PCA9555_INPUT_PORT_0);
	return pinout;
}

uint8_t PCA9555_InitPort(I2C_HandleTypeDef hic, uint16_t portDir, uint16_t portInit, uint8_t adr)
{
	// 1 - Вход
	// 0 - Выход
	HAL_StatusTypeDef stat;
	uint8_t mas_data[2];
			mas_data[0] =  portDir;
			mas_data[1] = (portDir<<8)&0xFF;
	stat = Transmit2PCA9555_R1(hic, adr, PCA9555_CONFIG_PORT_0,mas_data[0]);
	stat = Transmit2PCA9555_R1(hic, adr, PCA9555_CONFIG_PORT_1,mas_data[1]);
			mas_data[0] =  portInit;
			mas_data[1] = (portInit>>8)&0xff;
	stat = Transmit2PCA9555(hic, adr, PCA9555_OUTPUT_PORT_0,mas_data[0]);
	stat = Transmit2PCA9555(hic, adr, PCA9555_OUTPUT_PORT_1,mas_data[1]);
	return stat;
}

Загрузки

Где купить

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии