本帖最后由 dong_abc 于 2011-10-23 19:00 编辑
经典的状态机模式按键扫描,把书本上的一些程序改造,调试之后如下,个人感觉动手调试是最重要的。
key.c文件
#include "key.h"
// 按键输入口
#define key_input() inpw((uint32_t)&GPIOB->IN)
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
void Key_Init(void)
{
GPIOB->MD.PMD14=0;
GPIOB->MD.PMD15=0;
}
uint32_t Key_Scan(void)
{
static uint32_t key_state = 0, key_time = 0;
uint32_t key_press, key_return = 0;
key_press = key_input()&0xc000;
switch (key_state)
{
case key_state_0:
if (key_press!=0xc000) key_state = key_state_1;
break;
case key_state_1:
if (key_press!=0xc000)
{
switch (key_press)
{
case 0x4000: key_return=1;
break;
case 0x8000: key_return=2;
break;
default:
break;
}
//printf("key_press:0x%04x\n", key_press);
key_state = key_state_2;
key_time = 0;
}
else
key_state = key_state_0;
break;
case key_state_2:
if (key_press==0xc000) key_state = key_state_0;
else if (++key_time >= 50)
{
//key_state = key_state_3;
//key_return = 3;
key_time = 0;
switch (key_press)
{
case 0x4000: key_return=3;
break;
case 0x8000: key_return=4;
break;
default:
break;
}
}
break;
/*
case key_state_3:
if (key_press&(1<<14))
key_state = key_state_0; // 按键已释放,转换到按键初始态
else
{
if (++key_time >= 25) // 按键时间计数
{
key_time = 0; // 按下时间>0.5s,清按键计数器
key_return = 2; // 输出"2"
}
}
break;
*/
default:
break;
}
return key_return;
}
void Key_Proc(void)
{
switch (Key_Scan())
{
case 1:
outpw((uint32_t)&GPIOA->DOUT, inpw((uint32_t)&GPIOA->IN) ^ (1 << 4));
break;
case 2:
outpw((uint32_t)&GPIOA->DOUT, inpw((uint32_t)&GPIOA->IN) ^ (1 << 5));
break;
case 3:
outpw((uint32_t)&GPIOA->DOUT, inpw((uint32_t)&GPIOA->IN) ^ (1 << 4));
break;
case 4:
outpw((uint32_t)&GPIOA->DOUT, inpw((uint32_t)&GPIOA->IN) ^ (1 << 5));
break;
default:
break;
}
}
key.h文件
#include "main.h"
#ifndef __NUC1xxKey_H__
#define __NUC1xxKey_H__
extern void Key_Init(void);
extern uint32_t Key_Scan(void);
extern void Key_Proc(void);
#endif //__NUC1xxKey_H__
key.rar
(1.05 KB)
|