跳转至

按键扫描(KEY SCAN)


1、简介

CI14LP芯片内置按键扫描控制器(KEY SCAN),支持矩阵键盘行列扫描方式,最多支持8行×8列共64个按键。控制器自动完成扫描与去抖处理,按键按下时产生中断并给出按键行列值,CPU无需轮询扫描,降低功耗与占用。

特性:

  • 支持8行×8列矩阵按键
  • 按键有效电平可配置(高/低)
  • 内置滤波防抖(扫2次以上才上报中断)
  • 两种中断模式:存在有效按键上报 / 首次按下上报
  • 扫描间隔时间可配(基于8K时钟)

2、API

函数名 描述
key_scan_init 按键扫描初始化(结构体配置)
key_scan_set_io_mode 配置IO为行/列功能
key_scan_enable 按键扫描使能/关闭
key_scan_irq_mask_config 按键扫描中断屏蔽配置
key_scan_get_irq_mask_status 获取屏蔽后中断状态
key_scan_get_irq_raw_status 获取原始中断状态
key_scan_clear_irq 清除按键扫描中断
key_scan_get_key 获取按键值(行列键值)

3、关键类型

类型 说明
key_scan_valid_level_t 有效电平:KEY_SCAN_VALID_LEVEL_LOW(低有效,VCC接3.3V)、KEY_SCAN_VALID_LEVEL_HIGH(高有效,VCC接GND)
key_scan_irq_mode_t 中断模式:KEY_SCAN_IRQ_MODE_VALID(存在有效按键即上报)、KEY_SCAN_IRQ_MODE_FIRST(首次按下才上报)
key_scan_io_set_t IO行列选择:KEY_SCAN_IO_FOR_ROW(行)、KEY_SCAN_IO_FOR_COL(列)
key_scan_irq_t 中断类型:KEY_SCAN_IRQ_SCAN_OVER(扫描完成)、KEY_SCAN_IRQ_ERR(行列配置重合错误)、KEY_SCAN_IRQ_ALL
key_scan_config_t 初始化结构体:valid_level、irq_mode、filter_en(防抖使能)、scan_time(扫描间隔,1~256,8K时钟基准)
key_scan_msg_t 键值结构体:row(行号18)、col(列号18)

4、示例

1) 以下代码初始化按键扫描并配置2×2矩阵按键(4个按键):

#include "ci14lp_key_scan.h"
#include "ci14lp_scu.h"

void key_scan_demo(void)
{
    key_scan_config_t config;

    //打开按键扫描外设时钟
    scu_set_device_clock_en(HAL_KEYSCAN_BASE, ENABLE);

    config.valid_level = KEY_SCAN_VALID_LEVEL_LOW;  //低电平有效
    config.irq_mode    = KEY_SCAN_IRQ_MODE_FIRST;   //首次按下上报
    config.filter_en   = ENABLE;                    //滤波防抖
    config.scan_time   = 20;                        //扫描间隔

    key_scan_init(&config);

    //配置IO为行/列(PA0、PA1为行,PA2、PA3为列)
    key_scan_set_io_mode(PA0, KEY_SCAN_IO_FOR_ROW, ENABLE);
    key_scan_set_io_mode(PA1, KEY_SCAN_IO_FOR_ROW, ENABLE);
    key_scan_set_io_mode(PA2, KEY_SCAN_IO_FOR_COL, ENABLE);
    key_scan_set_io_mode(PA3, KEY_SCAN_IO_FOR_COL, ENABLE);

    //使能扫描
    key_scan_enable(ENABLE);
}

2) 按键中断处理函数示例(读取键值):

#include "ci14lp_key_scan.h"
#include <string.h>

void KEYSCAN_IRQHandler(void)
{
    key_scan_msg_t key;

    if (key_scan_get_irq_mask_status(KEY_SCAN_IRQ_SCAN_OVER))
    {
        //读取按键值(行号+列号)
        memset(&key, 0, sizeof(key));
        key.row = key_scan_get_key();

        mprintf("key pressed\n");
        key_scan_clear_irq(KEY_SCAN_IRQ_SCAN_OVER);
    }
    key_scan_clear_irq(KEY_SCAN_IRQ_ALL);
}

5、其它

  • 使用按键扫描功能时,相关引脚无需再配置为GPIO功能,key_scan_set_io_mode 会完成复用切换。
  • key_scan_get_key 返回按键行列信息,行列号均为1~8。
  • KEY_SCAN_IRQ_ERR中断表示行列配置重合(同一IO同时配置为行和列),需要检查IO配置。

6、API 参考

本模块接口声明于 driver\ci14lp_chip_driver\inc\ci14lp_key_scan.h,实现位于 driver\ci14lp_chip_driver\src\ci14lp_key_scan.c。