You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Komodo环境下用ARM汇编编写虚拟键盘按键中断消抖文件

Komodo环境ARM汇编实现虚拟键盘中断与消抖方案

以下实现基于1-9数字键虚拟开发板的通用硬件映射规则,你可以根据你手里虚拟板的BSP包寄存器定义调整对应参数。


前置配置准备

首先提前定义开发板相关寄存器宏(需和你用的虚拟板地址匹配):

  • 虚拟键盘状态寄存器:KEY_VAL_REG 地址示例0x40002004,读寄存器返回当前按下键值,无按键返回0
  • 键盘中断状态寄存器:INT_STAT_REG 地址示例0x40002008,第2位为键盘中断触发标志位
  • 键盘中断使能寄存器:INT_EN_REG 地址示例0x4000200C,第2位置1开启键盘中断
  • 中断挂起清除寄存器:INT_PEND_REG 地址示例0x40002010,对应位写1清除中断挂起

需要定义三个全局变量:

  • key_debounce_cnt:消抖计数器,单位ms
  • key_press_flag:有效按键按下标志位,1表示有未读取的有效按键
  • key_value:存储有效按键的键值(1-9)

1. 基础初始化流程

  • 配置虚拟键盘对应IO为输入模式,设置中断触发方式为下降沿触发(对应按键按下的电平变化)
  • 配置NVIC中断优先级,键盘外部中断优先级高于SysTick定时器中断,避免消抖逻辑被打断
  • 配置SysTick定时器为1ms中断,用于消抖计时
  • 初始化全局变量为0,开启键盘中断和SysTick定时器

2. 核心中断代码实现

所有中断服务函数需遵循ARM AAPCS调用规范,进入时保护用到的寄存器,退出前清除中断挂起位

2.1 键盘外部中断服务函数

KEY_IRQHandler
    PUSH    {R0-R3, LR}        ; 保护现场寄存器
    LDR     R0, =INT_STAT_REG
    LDR     R1, [R0]
    TST     R1, #(1<<2)        ; 校验是否为键盘触发的中断
    BEQ     KEY_IRQ_EXIT
    
    ; 临时关闭键盘中断,避免消抖过程中重复触发
    LDR     R0, =INT_EN_REG
    LDR     R1, [R0]
    BIC     R1, #(1<<2)
    STR     R1, [R0]
    
    ; 初始化消抖计数器为20ms(可根据虚拟板抖动模拟参数调整为10-30ms)
    LDR     R0, =key_debounce_cnt
    MOV     R1, #20
    STR     R1, [R0]
    
KEY_IRQ_EXIT
    ; 清除键盘中断挂起位
    LDR     R0, =INT_PEND_REG
    MOV     R1, #(1<<2)
    STR     R1, [R0]
    POP     {R0-R3, PC}        ; 恢复现场返回

2.2 SysTick中断服务函数(消抖逻辑)

SysTick_Handler
    PUSH    {R0-R3, LR}
    LDR     R0, =key_debounce_cnt
    LDR     R1, [R0]
    CMP     R1, #0
    BEQ     SYSTICK_EXIT       ; 无待消抖的按键直接退出
    
    SUB     R1, #1             ; 计数器每1ms减1
    STR     R1, [R0]
    CMP     R1, #0
    BNE     SYSTICK_EXIT       ; 未到消抖时长直接退出
    
    ; 消抖时长到,重新读取按键状态确认是否为有效按下
    LDR     R0, =KEY_VAL_REG
    LDR     R1, [R0]
    CMP     R1, #0
    BEQ     KEY_JITTER         ; 按键已松开,判定为抖动
    
    ; 按键有效,存储键值、置位按下标志
    LDR     R0, =key_value
    STR     R1, [R0]
    LDR     R0, =key_press_flag
    MOV     R1, #1
    STR     R1, [R0]

KEY_JITTER
    ; 重新开启键盘中断,等待下一次按键触发
    LDR     R0, =INT_EN_REG
    LDR     R1, [R0]
    ORR     R1, #(1<<2)
    STR     R1, [R0]

SYSTICK_EXIT
    POP     {R0-R3, PC}

3. 主程序调用逻辑

主程序只需要轮询key_press_flag即可:

  1. 当检测到key_press_flag为1时,读取key_value拿到1-9的对应键值
  2. 业务逻辑处理完成后将key_press_flag清零,等待下一次按键

内容的提问来源于stack exchange,提问作者anon1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 21:48:04