开发板
K210开发板
实验目的
本次测试主要学习 K210 的拨轮开关 keypad 利用状态机的方式检测按键事件。
实验元件
拨轮开关 keypad、RGB 灯
实验原理
拨轮开关 keypad 是通过拨动开关柄使电路接通或断开,从而达到切换电路的目的,拨轮开关的原理是经过人为的操作,控制对应电路接通,这里的作用是接通 GND,使 IO 口电平变为低电平,松开时弹簧自动复位的过程。利用定时器扫描 keypad 的状态,在定时器扫描过程中计算 keypad 状态的时间值,从而读取keypad 三个通道的按键状态,存入 FIFO 队列机制,在通过函数回调的方式执行每个状态需要处理的事件,或者可以通过读取按键的状态,再根据状态的不同进行处理事件。
实验过程
- 首先根据上面的硬件连接引脚图,K210 的硬件引脚和软件功能使用的是FPIOA 映射关系。
- 由于需要使用定时器中断,所以需要初始化系统中断和使能全局中断。
- 在使用 RGB 灯前需要初始化,这里可以单独只初始化一个灯,或者全部灯一起初始化,当然我们选择的是全部灯一起初始化。
- 初始化 keypad,设置 GPIO 为上拉输入模式,把 FIFO 清零,再设置 keypad三个通道的初始数据,最后是初始化并启动定时器。
- 定时器使用的是定时器 0 的通道 0,定时中断时间为 1 毫秒,也就是每毫秒扫描一次 keypad。
- 在扫描 keypad 函数中有两种方式可以选择,默认是状态机方式扫描,更快更方便,第二种是循环判断的方式。
- 这里以状态机扫描方式来说明一下工作原理,由于 keypad 的特性,所以同一时间只能有一个通道是有效的,所以获取到对应通道的 ID,只处理有效的ID 就可以。首先没有触发事件的是否都在 EN_KEY_NULL 这个状态中,当检测到key_state 状态改变,也就是有效触发按键事件,就改变状态 key_state 为EN_KEY_DOWN。
在每一次扫描结束时,都会把当前的状态传给 prev_key_state,表示上一次状态。
EN_KEY_DOWN 状态下,会先判断状态是否保持,相当于消抖功能,然后上报按键按下事件,并存入 FIFO,执行回调函数,修改状态为 EN_KEY_DOWN_RECHECK。
EN_KEY_DOWN_RECHECK 状态主要处理长按、连发和松开,长按的功能是每次扫描加一个 KEY_TICKS 的值,这个是 1ms 扫描,所以 KEY_TICKS 的值为 1,当长按的计数 long_count 大于或等于设定的长按超时时间 long_time,则触发事件存入 FIFO,并执行回调函数。长按事件触发后,紧跟着就是连发的事件,连发的工作机制在于每次触发连发事件后执行回调函数,还会把 repeat_count 清空,等待下一次 repeat_count 溢出,再次执行任务,最后是按键松开的情况,切换到EN_KEY_UP 状态。
EN_KEY_UP 状态也会先判断前后两次状态的值是否一致,如果一致就表示按键松开了,然后触发松开的回调函数,状态修改为 EN_KEY_UP_RECHECK。
EN_KEY_UP_RECHECK 的 功 能 主 要 是 确 定 已 经 松 开 , 并 且 修 改 状 态 为EN_KEY_NULL
最后也就是前面讲过的把当前状态保存到 prev_key_state 中,作为下一次扫描的上一次状态
- 保存某个按键的状态到 FIFO 中。
- 读出 keypad 的一个事件,默认为 EN_KEY_NONE,其他数字对应不同事件。
- 如果需要修改触发的时间,可以修改以下参数。KEY_TICKS 为扫描周期,与定时器的中断周期保持一致就可以,如果不一致会导致下面的时间有差异;KEY_FILTER_TIME 为消抖时间; KEY_LONG_TIME 为长按的触发时间;KEY_REPEAT_TIME 是指长按触发后的重复触发的时间。
- 初始化 keypad 完成后,就可以获取 keypad 的事件,总共有两种方式,第一种是通过设置回调函数的方式,第二种是通过读取状态值的方式。 第一种:设置 keypad 三个通道的事件回调函数,由于同一时间内只能有一个通道是有效的,所以把三个通道的不同状态的回调函数设置为同一个,当然也可以分别定义一个函数作为回调函数。
这里为了方便,回调函数的内容比较简单: 按下事件:亮红灯,
松开事件:蓝色灯灭,
长按事件:红灯灭,
重复(连发)事件:蓝色灯闪烁。
- 第二种:通过读取状态值的方式,打印当前按键的状态值。
- 编译调试,烧录运行 进入自己项目 build目录,运行以下命令编译。
实验现象
烧录完成固件后,系统会弹出一个终端界面,如果没有弹出终端界面的可以打开串口助手显示调试内容。
终端会打印“Please control keypad to get status!”提示操作 keypad来读取 keypad 的状态;这里设置的 keypad 三个通道的功能都是一样的,所以以中间的那个按键来举例,当按下时,红灯亮,并且打印按下提示,如果立即松开则打印松开的提示,但是红灯不会熄灭,如果长按约 1 秒钟,红灯熄灭,并且打印长按提示,如果继续按住不放,就会进入重复打印的事件,功能是每 0.2 秒打印一次重复提示,蓝色灯每 0.4 秒闪烁一次,此时松开蓝色灯熄灭。
实验总结
- keypad 的内部原理其实是三个按键,只不过同一时间只能触发一个按键按 下。
- 通过定时器扫描 keypad 的方式,可以检测出 keypad 的事件,并且设置回 调函数。
- keypad 事件可以通过两种方式获取,第一种是设置回调函数,第二种是读 取 keypad 的状态值