按键扫描(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。