|
|
|
|
基板種類 | 最大 I/O数 |
ATmega32u4 Pro Micro | 18本 |
ATmega32u4 Elite-C V4 | 24本 |
RP2040 Raspberry Pi Pico基板 | 26本 |
STM32 Blue Pill基板等 | 33本 |
PCF8574 | 8 bit | 8-bit I2C/SMBus I/O expander with interrupt |
PCF8575 | 16 bit | 16-bit I2C/SMBus I/O expander with interrupt |
TCA9555 | 16 bit | 16-bit I2C/SMBus I/O expander with interrupt weak pull-up & config registers |
TCA6424 | 24 bit | 24-bit translating I2C/SMBus I/O expander with interrupt reset & config registers |
MCP23017 | 16 bit | 16-Bit I2C I/O Expander with Serial Interface |
今回購入![]() 3個セット PCF8574 IO拡張ボード I2C Arduino用 開発ボード ASIN: B07BW3VL3C |
今回購入![]() PCF8575 IIC I2C I/O 拡張シールドモジュール 16 ビット SMBus I/O ポート新 ASIN: B083ZWQGMS ※ 基板の色が違うだけ |
![]() WINGONEER MCP23017-E/SS I2Cインターフェイス16チャンネルIO拡張モジュール互換 C51 IIC入力および出力拡張ボード ASIN: B081ZYXW88 |
![]() HiLetgo TCA9548A I2C IIC マルチプレクサ ブレークアウト ボード 8チャンネル 拡張ボード ASIN: B078W4YLFG |
74HC4051 | 8 bit | 8:1 | 1-channel analog mutliplexer |
74HC4067 | 16 bit | 16:1 | 1-channel analog multiplexer |
前回購入![]() 8チャンネル74HC4051アナログマルチプレクサーデマルチプレクサーモジュールラズベリーパイ用単極オクタルスローアナログスイッチ ASIN: B07ZCP69KS |
前回購入![]() Ren He 3個セット CD74HC4067 高速 CMOS 16チャンネル デジタル アナログ マルチプレクサ 多重 ブレイクアウト ボード モジュール Arduinoと互換 ASIN: B0953LPVKJ 注意:黄色の接続ピンは付属しません |
![]() ACEIRMC CD74HC4067 16チャンネル アナログデジタルマルチプレクサー ブレークアウトボードモジュール Arduino 2V-6V マイクロコントローラー用 16デバイス RXライン 10個 ASIN: B08XV26WPS |
CUSTOM_MATRIX = lite # I2C PCF8574 and PCF8575 SRC += matrix.c QUANTUM_LIB_SRC += i2c_master.c
void matrix_init_custom(void) { // TODO: initialize hardware here } bool matrix_scan_custom(matrix_row_t current_matrix[]) { bool matrix_has_changed = false; // TODO: add matrix scanning routine here return matrix_has_changed; }
I2C アドレス(基本) | I2C アドレス(Write) | I2C アドレス(Read) | |||
Col出力 | PCF8574(8bit GPIO) | 0x20(A2=L A1=L A0=L) | 0x40 | 0x41 | 青基板 |
Row入力 | PCF8574(8bit GPIO) | 0x24(A2=H A1=L A0=L) | 0x48 | 0x49 | 赤基板 |
// Copyright 2021 Y.Sakamoto (@FREEWING-JP) // SPDX-License-Identifier: GPL-2.0-or-later #include "matrix.h" #include "gpio.h" #include "i2c_master.h" #if (MATRIX_ROWS <= 8) # define ROW_TYPE uint8_t #elif (MATRIX_ROWS <= 16) # define ROW_TYPE uint16_t #elif (MATRIX_ROWS <= 32) # define ROW_TYPE uint32_t #endif #define ROW_SHIFTER ((ROW_TYPE)1) #define PCF857x_I2C_TIMEOUT 1000 #define I2C_WRITE 0x00 #define I2C_READ 0x01 // Col Output PCF8574 (A2=L, A1=L, A0=L) #define I2C_ADDR_COL 0x20 #define I2C_ADDR_COL_WRITE ((I2C_ADDR_COL << 1) | I2C_WRITE) #define I2C_ADDR_COL_READ ((I2C_ADDR_COL << 1) | I2C_READ) // Row Input PCF857x (A2=H, A1=L, A0=L) #define I2C_ADDR_ROW 0x24 #define I2C_ADDR_ROW_WRITE ((I2C_ADDR_ROW << 1) | I2C_WRITE) #define I2C_ADDR_ROW_READ ((I2C_ADDR_ROW << 1) | I2C_READ) // Col Output PCF8574 8bit static void col_init(void) { // All Output 'H' uint8_t buf[] = { 0b11111111 }; i2c_transmit(I2C_ADDR_COL_WRITE, buf, sizeof(buf), PCF857x_I2C_TIMEOUT); } // Row Input PCF8574 8bit / PCF8575 16bit static void row_init(void) { #if (MATRIX_ROWS <= 8) // Row Input PCF8574 8bit // All Input Pull Up uint8_t buf[] = { 0b11111111 }; i2c_transmit(I2C_ADDR_ROW_WRITE, buf, sizeof(buf), PCF857x_I2C_TIMEOUT); #elif (MATRIX_ROWS <= 16) // Row Input PCF8575 16bit // All Input Pull Up uint8_t buf[] = { 0b11111111, 0b11111111 }; i2c_transmit(I2C_ADDR_ROW_WRITE, buf, sizeof(buf), PCF857x_I2C_TIMEOUT); #elif (MATRIX_ROWS <= 32) TODO() #endif } // Col Output PCF8574 8bit static void select_col(uint8_t col) { // Col Output 'L' uint8_t colByte = ~(1 << col); uint8_t buf[] = { colByte }; i2c_transmit(I2C_ADDR_COL_WRITE, buf, sizeof(buf), PCF857x_I2C_TIMEOUT); } // Row Input PCF8574 8bit / PCF8575 16bit static ROW_TYPE read_rows(void) { #if (MATRIX_ROWS <= 8) // Row Input PCF8574 8bit uint8_t buf[1]; i2c_receive(I2C_ADDR_ROW_READ, buf, sizeof(buf), PCF857x_I2C_TIMEOUT); return ~buf[0]; #elif (MATRIX_ROWS <= 16) // Row Input PCF8575 16bit uint8_t buf[2]; i2c_receive(I2C_ADDR_ROW_READ, buf, sizeof(buf), PCF857x_I2C_TIMEOUT); return ~((buf[1] << 8) | buf[0]); #elif (MATRIX_ROWS <= 32) TODO() #endif } void matrix_init_custom(void) { i2c_init(); col_init(); row_init(); } // MATRIX_ROWS = 4 // MATRIX_COLS = 4 // matrix_row_t = uint8_t bool matrix_scan_custom(matrix_row_t current_matrix[]) { // Scan Keyboard Matrix ROW_TYPE tmp[MATRIX_COLS]; ROW_TYPE* pt = tmp; for (uint8_t col = 0; col < MATRIX_COLS; ++col) { // MSB = col 7, LSB = col 0 select_col(col); matrix_io_delay(); *pt++ = read_rows(); } col_init(); // Check Keyboard Matrix has Changed bool matrix_has_changed = false; matrix_row_t* p = current_matrix; for (uint8_t row = 0; row < MATRIX_ROWS; ++row) { ROW_TYPE and_row = (ROW_SHIFTER << row); matrix_row_t now_rows = 0; int8_t col = MATRIX_COLS; while (--col >= 0) { now_rows <<= 1; now_rows |= ((tmp[col] & and_row) ? 1 : 0); } if (*p != now_rows) { *p = now_rows; matrix_has_changed = true; } ++p; } return matrix_has_changed; }
// Copyright 2021 Y.Sakamoto (@FREEWING-JP) // SPDX-License-Identifier: GPL-2.0-or-later /* key matrix size */ #define MATRIX_ROWS 4 #define MATRIX_COLS 4 /* * Keyboard Matrix Assignments * * Change this to how you wired your keyboard * COLS: AVR pins used for columns, left to right * ROWS: AVR pins used for rows, top to bottom * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) * */ #define MATRIX_ROW_PINS { NO_PIN, NO_PIN, NO_PIN, NO_PIN } #define MATRIX_COL_PINS { NO_PIN, NO_PIN, NO_PIN, NO_PIN } // #define UNUSED_PINS /* COL2ROW, ROW2COL */ // #define DIODE_DIRECTION COL2ROW /* * the delay in microseconds when between changing matrix pin state and reading values */ #define MATRIX_IO_DELAY 30 // 30us, 8*30us = 8us = 0.240ms