KeyboardReader 及其实现
头文件: utility/Keyboard/KeyboardReader/KeyboardReader.h
KeyboardReader 是一个用于读取物理按键矩阵的抽象接口。有两个具体实现,根据板型自动选择。
Point2D_t
表示按键矩阵上的物理位置:
- x — 列索引(0–13)
- y — 行索引(0–3)
KeyboardReader(抽象基类)
class KeyboardReader {
public:
virtual ~KeyboardReader() = default;
virtual void begin();
virtual void update();
const std::vector<Point2D_t>& keyList() const;
protected:
std::vector<Point2D_t> _key_list;
};
| 方法 | 说明 |
|---|---|
begin() |
初始化硬件。在子类中重写以配置 GPIO / I2C。 |
update() |
扫描按键矩阵并填充 _key_list。在子类中重写。 |
keyList() |
返回当前按下的按键坐标列表。 |
IOMatrixKeyboardReader
头文件: utility/Keyboard/KeyboardReader/IOMatrix.h
用于: M5Cardputer(标准版)
GPIO 矩阵扫描实现。使用 3 个输出引脚和 7 个输入引脚来扫描一个 4 行 × 7 列 × 2 的矩阵(通过时分复用实现 4×14)。
引脚分配
| 角色 | 引脚 |
|---|---|
| 输出(行选择) | 8、9、11 |
| 输入(列读取) | 13、15、3、4、5、6、7 |
工作原理
begin()— 将输出引脚配置为OUTPUT,输入引脚配置为INPUT_PULLUP。update()— 迭代 8 步(0–7),在输出引脚上设置 3 位行地址,然后读取 7 个输入引脚。前 4 步映射到列x_1,后 4 步映射到列x_2(参见X_map_chart)。检测到的按键按下以Point2D_t形式推入_key_list。
class IOMatrixKeyboardReader : public KeyboardReader {
public:
void begin() override;
void update() override;
private:
const std::vector<int> output_list = {8, 9, 11};
const std::vector<int> input_list = {13, 15, 3, 4, 5, 6, 7};
const Chart_t X_map_chart[7];
void set_output(const std::vector<int>& pinList, uint8_t output);
uint8_t get_input(const std::vector<int>& pinList);
};
TCA8418KeyboardReader
头文件: utility/Keyboard/KeyboardReader/TCA8418.h
用于: M5Cardputer-ADV
基于 I2C 的键盘驱动,使用 TCA8418 按键矩阵控制器芯片。中断驱动:当有按键事件时,GPIO ISR 设置标志位。
硬件参数
| 项目 | 值 |
|---|---|
| I2C 总线 | 内部(m5::In_I2C) |
| I2C 地址 | 0x34 |
| 中断引脚 | GPIO 11 |
| 矩阵大小 | 7 行 × 8 列 |
工作原理
begin()— 通过 I2C 初始化 TCA8418,配置 7×8 矩阵,在 GPIO 11 上附加CHANGE中断。update()— 在主循环中调用。如果 ISR 标志被设置,从 TCA8418 的 FIFO 读取按键事件,将行/列重映射到 M5Cardputer 坐标系统,并更新_key_list(添加新的按下事件,移除释放事件)。
class TCA8418KeyboardReader : public KeyboardReader {
public:
TCA8418KeyboardReader(int interrupt_pin = -1);
void begin() override;
void update() override;
private:
struct KeyEventRaw_t { bool state; uint8_t row; uint8_t col; };
std::unique_ptr<Adafruit_TCA8418> _tca8418;
volatile bool _isr_flag;
int _interrupt_pin;
static void IRAM_ATTR gpio_isr_handler(void* arg);
};
| 构造函数参数 | 默认值 | 说明 |
|---|---|---|
interrupt_pin |
-1(自动 → GPIO 11) |
按键事件的中断引脚 |
Adafruit_TCA8418(内部驱动)
头文件: utility/Adafruit_TCA8418/Adafruit_TCA8418.h
TCA8418 芯片的内部 I2C 驱动,继承自 m5::I2C_Device。从 Adafruit 的库适配而来,使用 M5Unified 的 I2C 抽象。通常仅由 TCA8418KeyboardReader 内部使用。
class Adafruit_TCA8418 : public m5::I2C_Device {
public:
Adafruit_TCA8418(uint8_t i2c_addr = 0x34, uint32_t freq = 400000,
m5::I2C_Class* i2c = &m5::In_I2C);
bool begin();
bool matrix(uint8_t rows, uint8_t columns);
uint8_t getEvent();
uint8_t flush();
void enableInterrupts();
void disableInterrupts();
// ... GPIO、消抖等控制方法 ...
};