STM8S之独立按键IO口设置及按下事件问题

详见博客:http://blog.csdn.net/freeape/article/details/46793457

1 GPIO设置

                STM8 I/O 口引脚配置表

Px_DDR Px_CR1 Px_CR2 I/O 方式 引脚状态
0 0 0 输入 悬浮输入
0 0 1 输入 上拉输入
0 1 0 输入 中断悬浮输入
0 1 1 输入 中断上拉输入
1 0 0 输出 开漏输出
1 1 0 输出 推挽输出
1 x 1 输出 输出(最快速度为10MHZ)

对STM8S的IO配置,我们只需要操作五个寄存器就行了:

  • 输出数据寄存器 (ODR)
  • 输入数据寄存器 (IDR)
  • 数据方向寄存器 (DDR)
  • 控制寄存器1(CR1)
  • 控制寄存器2(CR2)

2 按键检测

  在做独立按键检测的时候,设置成上拉输入不能实现功能,设置成中断悬浮输入就可以了。
  两次短按键之间的时间间隔大约在300ms~600ms之间。一次短按键按下的时间大约在14ms~26ms之间;

2.1 连续按键检测(短按+长按)

定时器TIM1 + 按键 = 连续按键检测(短按键+长按键)
两个标记:

  • 短按+长按—flag0
  • 短按后时间在规定范围之内—flag1

如果两个标记都满足,则开/关电源;每次按键都启动按键计时;

当两次按键的时间间隔在300ms~600ms之间的时候,怎么得到第一次(短按)和第二次(长按)按键之间的时间呢?
  如果判断了是短按,则开启计时,同时将第一次短按flag置一,超过600ms停止计时并清零,等待第二次的按键;有了第二次的按键之后,在短按置一flag条件中中断计时,判断是否在规定范围之内的时间间隔,是则将flag1置一;并接下来判断该按键是长按还是短按,如果是长按,则将flag0置一,满足flag0、flag1均置一,则是连续按键。

3 关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
return =
0 : No Key Press
1 : Single Key Press
2 : 将长按作为一次单独按键,并执行Single Key Press功能
3 : Double Key Press
*/

unsigned int Key_Scan(void)
{

unsigned int count = 0;

if(0 == KEY)
{
Delay(2);
if(0 == KEY)
{
if(1 == keytimesFlag)
{
afterOnceShortPressFlag = 0;
if((afterOnceShortPressCount <=30)
&& (afterOnceShortPressCount > 15))
{
isSetTimeFlag = 1;
}
else isSetTimeFlag = 0;
}
keyFlag = 1;
while(!KEY);
keyFlag = 0;
count = keyCount;
keyCount = 0;
}
else
{
count = 0;
}
}

if(count >= 200)
{
if(1 == isSetTimeFlag)
{
isSetTimeFlag = 0;
keytimesFlag = 0;
return 3;
}
else
{
keytimesFlag = 0;
return 2;
}
}
else if(count >= 4)
{
afterOnceShortPressFlag = 1;
afterOnceShortPressCount = 0;
keytimesFlag = 1;
return 1;
}
else return 0;
}

在定时周期为10ms的定时器中断函数里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@far @interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)
{

TIM1_SR1 &=~(0x01);
if(1 == keyFlag)
{
++keyCount;
}
else ;
if(1 == afterOnceShortPressFlag)
{
++afterOnceShortPressCount;
if(afterOnceShortPressCount > 80)
{
afterOnceShortPressFlag = 0;
afterOnceShortPressCount = 0;
keytimesFlag = 0;
}
}
else ;
}

  另参见使用外部中断长按键识别:使用外部中断识别长按键