KEYSCAN
示例列表
本章介绍 KeyScan 示例的详细信息。RTL87x2G 为 KeyScan 外设提供以下示例。
功能概述
RTL87x2G 支持可配置的 12 行 * 20 列按键矩阵,并带有按键扫描功能。每个 IO PAD 都可以配置为按键扫描的任意行或列引脚。 KeyScan 需要与外部键盘矩阵一起使用。
特性列表
支持 12(行)* 20(列)矩阵扫描。
可配置行数(1-12)、列数(1-20)。
支持硬件去抖动,去抖动时间可配置。
扫描时钟可配置。
支持多键检测,最多可同时按下 26 个键。
支持周期性扫描,扫描周期可配置。
26 字节 FIFO 深度。
支持自动扫描和手动扫描。
支持所有按键释放的硬件检测。
扫描流程
Keyscan 的扫描流程如图所示:

KeyScan 扫描流程示意图
在空闲状态下,所有的 row[x] 作为输入,处于上拉状态,所有的 column[y] 作为输出,输出低电平。
当任意按键被按下时,在某一个 row 中会检测到低电平,触发 KeyScan 硬件扫描动作。
等待 debounce timer 后,开始第一次扫描。
首先将 column[0] 拉低,其他的 column 拉高,依次检测 row[0],row[1],…,row[N]。
如果检测到 row[0] 被拉低,则可以确定 (row[0], column[0]) 被按下,否则该键没有被按下。以此类推继续扫描其他 row。
切换到 column[1] 拉低,其他的 column 拉高,依次检测 row[0],row[1],…,row[N],直到最后一个 column[N] 拉低,其他的 column 拉高,扫描完成。
此时一次扫描结束,扫描的结果将填入 Keyscan FIFO,如果开启
KEYSCAN_INT_SCAN_END
中断,将会触发该中断。经过 scan interval 时间后,会进行第二次全局扫描,扫描结束后进行相同操作。
如果在某次扫描检测到没有任何按键按下,则会开始 all release timer 的计时,此时所有 column 拉低。等待 all release timer 计时结束后仍然没有检测到任意 row 被拉低,则代表此时所有按键 release。如果开启
KEYSCAN_INT_ALL_RELEASE
中断,则会触发该中断。
Keyscan 扫描分为手动扫描模式和自动扫描模式。
手动扫描模式
在 Keyscan 初始化中配置 KEYSCAN_InitTypeDef::scanmode
为 KeyScan_Manual_Scan_Mode
,以配置 Keyscan 为手动扫描模式。
在手动扫描模式下,触发 Keyscan 扫描的方式有两种:按键触发和寄存器触发。
按键触发:在使能 Keyscan 后,检测到外部有按键按下时才会触发扫描。在初始化中需要配置
KEYSCAN_InitTypeDef::manual_sel
为KeyScan_Manual_Sel_Key
。寄存器触发:在初始化 Keyscan 后,调用
KeyScan_Cmd()
函数以触发 Keyscan 扫描,外部按键无法触发扫描。在初始化中需要配置KEYSCAN_InitTypeDef::manual_sel
为KeyScan_Manual_Sel_Bit
。
在手动扫描模式下,Keyscan 只会进行一次扫描,扫描结束后会触发 KEYSCAN_INT_SCAN_END
中断。
自动扫描模式
在 Keyscan 初始化中配置 KEYSCAN_InitTypeDef::scanmode
为 KeyScan_Auto_Scan_Mode
,以配置 Keyscan 为自动扫描模式。
在自动扫描模式下,触发 Keyscan 扫描的方式为外部按键触发。可以通过设置 KEYSCAN_InitTypeDef::detectMode
来修改触发模式为边沿触发( KeyScan_Detect_Mode_Edge
)或电平触发( KeyScan_Detect_Mode_Level
)。
自动扫描模式下,Keyscan 会持续进行扫描,直到没有按键按下后触发 KEYSCAN_INT_ALL_RELEASE
中断。其中 KEYSCAN_INT_SCAN_END
中断可以被多次触发。
自动扫描的工作流程如下图所示。

自动扫描流程图
时钟分频
外设时钟将被分为两个通道。
KeyScan 扫描时钟是通过 keyscan_clk_div
的分频产生的。
Scan clock = Keyscan clock source (5MHz) / KEYSCAN_InitTypeDef::clockdiv
。
低电平延迟时钟是通过 keyscan_delay_div
的分频产生的,供相关定时器使用。
Delay clock = Scan clock / KEYSCAN_InitTypeDef::delayclk
。
key_scan_deb_timer
用于定时 debounce,debounce time = Delay clock * KEYSCAN_InitTypeDef::debouncecnt
。
key_scan_interval_timer
用于定时 scan interval,scan interval time = Delay clock * KEYSCAN_InitTypeDef::scanInterval
。
key_scan_release_timer
用于定时 release time,release time = Delay clock * KEYSCAN_InitTypeDef::releasecnt
。

KeyScan 时钟分频器示意图