|
最近家中内外交困,没有任何“重登机器人分坛主”的实际行动,先发个没有技术含量的串行按键驱动回馈各位热心坛友。
功能:
最大8按键检测,带消干扰;
4线制驱动(其中2线为共用SPI时钟、数据,1线锁存,1线KEY_FEED反馈);
类似PC键盘的按键重发(首次重发长延时,其后端延时,可调)。
74HC595串行按键检测电路 (原文件名:KeyBoard.JPG)
代码:
#include "key_board.h" /* 头文件啦,里面就一个函数声明,大家应该知道怎么写的 */
#include "chip.h" /* 一些WinAVR的类型定义等,如uint8_t */
#include "util.h"
#define SCAN_THREASHOLD 2 /* 重复判断多少次以上视为按键被按下 */
#define FIRST_REPEAT_THREASHOLD 20 /* 首次重复多少次视为按住不放 */
#define NORMAL_REPEAT_THREASHOLD 10 /* 首次重复以后,重复多少次视为按住不放 */
static uint8_t repeat_threashold = FIRST_REPEAT_THREASHOLD;
uint8_t get_key()
{
uint8_t i;
static uint8_t last_code, last_code_count;
static uint8_t last_key, last_key_repeat;
static uint8_t chk_repeat = 0;
for (i=0xFE; i!=0; i=(i<<1))
{
//
// Shift data & check ket feed
/* Start transmission */
SPDR = i;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)));
PORT_PIN_CLR (KEY_RCLK);
NOP ();
PORT_PIN_SET (KEY_RCLK);
delay_us(1);
if (!PORT_PIN_VALUE (KEY_FEED))
{
if (i == last_code)
{
/* 按下的键与上次相同 */
if (++last_code_count> SCAN_THREASHOLD)
{
last_key = i;
last_code_count = 0;
if( chk_repeat )
{
if (last_key_repeat++> repeat_threashold)
{
repeat_threashold = NORMAL_REPEAT_THREASHOLD;
return last_key;
}
else
return 0xFF;
}
else
{
// 首次检测到该按键,下次该检查重发啦
chk_repeat = 1;
repeat_threashold = FIRST_REPEAT_THREASHOLD;
return last_key;
}
}
}
else
{
/* 换了个键按下 */
last_code = i;
last_code_count = 0;
last_key = 0;
last_key_repeat = 0;
chk_repeat = 0;
repeat_threashold = FIRST_REPEAT_THREASHOLD;
}
break;
}
}
if (i == 0)
{
/* 没有键按下 */
last_code = 0;
last_code_count = 0;
last_key = 0;
last_key_repeat = 0;
chk_repeat = 0;
repeat_threashold = FIRST_REPEAT_THREASHOLD;
}
return 0xFF;
}
代码检测的是7个按键,但是改一下循环,就能够检测8个了,有兴趣的可以试试。 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|