|
发表于 2011-8-30 11:55:25
|
显示全部楼层
回复【114楼】packer
-----------------------------------------------------------------------
我用的STM32单片机,按键电路图如图1
图1.按键图 (原文件名:11.gif)
代码如下
/* filename: usart.c */
#include "STM32f10x.h"
#include "key.h"
#define key_input GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2) // 按键输入口
#define N_key 0 //无键
#define S_key 1 //单键
#define D_key 2 //双键
#define L_key 3 //长键
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
void KEY_PIN_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//使能按键的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
//配置按键为浮空输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
u8 key_driver(void)
{
static u8 key_state = key_state_0,key_time = 0;
u8 key_press,key_return;
key_press = key_input;
switch(key_state)
{
case key_state_0:
if(!key_press)
{
key_state = key_state_1;
}
break;
case key_state_1:
if(key_press)
{
key_time = 0;
key_state = key_state_2;
}
else
{
key_state = key_state_0;
}
break;
case key_state_2:
if(key_press)
{
key_return = S_key;
key_state = key_state_0;
}
else if (++key_time >= 100)
{
key_return = L_key;
key_state = key_state_3;
}
break;
case key_state_3:
if(key_press)
{
key_state = key_state_0;
}
break;
}
return key_return;
}
u8 key_read(void)
{
static u8 key_m = key_state_0, key_time_1 = 0;
u8 key_return = N_key,key_temp;
key_temp = key_driver();
switch(key_m)
{
case key_state_0:
if (key_temp == S_key )
{
key_time_1 = 0;
key_m = key_state_1;
}
else
{
key_return = key_temp;
}
break;
case key_state_1:
if (key_temp == S_key) // 又一次单击(间隔肯定<500ms)
{
key_return = D_key; // 返回双击键事件,回初始状态
key_m = key_state_0;
}
else
{ // 这里500ms内肯定读到的都是无键事件,因为长键>1000ms,在1s前低层返回的都是无键
if(++key_time_1 >= 50)
{
key_return = S_key; // 500ms内没有再次出现单键事件,返回上一次的单键事件
key_m = key_state_0; // 返回初始状态
}
}
break;
}
return key_return;
}
第一个函数是配置PC2为浮空输入,用于读取按键的电平,下面两个函数就是一样的。
主函数中调用
while (1)
{
if(user_key_time==0)
{
key_value = key_read();
switch(key_value)
{
case 0:
USART1_Puts("没有键盘按下的消息");
USART1_Putc(0x0D);USART1_Putc(0x0A);
break;
case 1:
USART1_Puts("单击键盘按下的消息");
USART1_Putc(0x0D);USART1_Putc(0x0A);
break;
case 2:
USART1_Puts("双击键盘按下的消息");
USART1_Putc(0x0D);USART1_Putc(0x0A);
break;
case 3:
USART1_Puts("长按键盘按下的消息");
USART1_Putc(0x0D);USART1_Putc(0x0A);
break;
default:break;
}
}
}
用串口显示是单键,双键还是长按还是没有键盘按下,目前是无论是否按键都提示没有键盘按下。 |
|