PIC18单片机:8x8点阵RA1列点上下移动异常问题求助
嘿,这个按键冲突的问题我在PIC18的点阵项目里也踩过坑!先给你拆解下问题根源,再聊聊XORWF能不能帮上忙——
问题出在哪?
你现在的代码应该是电平触发按键检测:只要RB0/RB5处于按下状态,就执行对应的移动逻辑。当两个键同时按下时,两个移动操作会被依次执行,导致位置计算异常(比如你说的下移,大概率是下移逻辑先执行,或者边界处理叠加后出现的结果)。
XORWF的正确打开方式
XORWF本身是PIC的位异或指令,用来直接处理位置移动并不合适(移位和异或是完全不同的操作),但它可以帮你解决按键检测的冲突问题——具体来说,用它来实现边沿触发的按键检测,并且可以快速判断是否同时按下两个键。
实现思路(用PIC汇编举例)
核心是通过XORWF对比当前PORTB状态和上一次的状态,捕捉按键从“未按下”到“按下”的边沿(只触发一次移动,而不是按住就连续执行),同时在检测到两个键同时按下时,直接跳过移动操作:
- 先定义两个变量存储状态:
pos EQU 0x20 ; 点的位置,初始值0x08 last_PORTB EQU 0x21 ; 保存上一次PORTB的状态
- 初始化代码:
MOVLW 0x08 MOVWF pos ; 设置初始位置 MOVF PORTB, W MOVWF last_PORTB ; 记录初始按键状态
- 按键处理逻辑:
key_check: ; 用XORWF检测按键状态变化 MOVF PORTB, W XORWF last_PORTB, W ; W = 当前PORTB ^ 上一次状态,变化的位会被置1 ANDLW 0x21 ; 只保留RB5(bit5)和RB0(bit0)的变化 BTFSC STATUS, Z ; 如果没有按键状态变化,直接跳过 GOTO end_key_check ; 判断是否两个按键同时按下 MOVF PORTB, W ANDLW 0x21 XORLW 0x21 ; 如果结果为0,说明RB5和RB0都是低电平(同时按下) BTFSC STATUS, Z GOTO end_key_check ; 同时按下时不执行任何移动 ; 处理RB5上移边沿(仅在按下瞬间触发) BTFSC PORTB, 5 ; RB5未按下(高电平)则跳过 BTFSC WREG, 5 ; 有状态变化(从高到低)则跳过 GOTO move_up ; 处理RB0下移边沿(仅在按下瞬间触发) BTFSC PORTB, 0 ; RB0未按下则跳过 BTFSC WREG, 0 ; 有状态变化则跳过 GOTO move_down GOTO end_key_check ; 上移逻辑(右移位置掩码,处理边界) move_up: MOVF pos, W RRNCF WREG, F ; 带进位右移一位(上移) BTFSC STATUS, Z ; 如果右移后为0(到达顶部) MOVLW 0x80 ; 循环到底部(可选,也可以停在0x01) MOVWF pos GOTO end_key_check ; 下移逻辑(左移位置掩码,处理边界) move_down: MOVF pos, W RLNCF WREG, F ; 带进位左移一位(下移) BTFSC STATUS, Z ; 如果左移后为0(到达底部) MOVLW 0x01 ; 循环到顶部(可选) MOVWF pos GOTO end_key_check ; 更新按键状态,结束检测 end_key_check: MOVF PORTB, W MOVWF last_PORTB ; 这里加你的点阵刷新代码 GOTO main_loop
额外建议
别忘了加按键消抖!可以在检测到边沿后,延时5-10ms再确认按键状态,避免机械抖动导致的误触发,这也能进一步减少同时按键的误判概率。
这样修改后,不仅能解决同时按键的异常问题,还能让按键操作更精准(按一次移动一次,而不是按住连续移动,如果你需要连续移动,可以在边沿触发后加个循环检测)。
内容的提问来源于stack exchange,提问作者Stefi Zuzu
相关产品推荐
相关产品推荐

