研究生
最后登录1970-1-1
在线时间 小时
注册时间2016-10-5
|
如标题所言,可以把这个 Key_scan( )直接扔到SYStick 10MS中断里面就可以了,很容易再加一个状态机外壳即可实现按键短按长按等功能,不需要频繁打开关闭定时器
Key_count 是扫描计数器,每次到中断判断一下是否上次有按键按下,没有就+1,上次有按键事件就保持计数器值再检测一次按键是否还按下,利用 Key_count 奇数和偶数间隔,可以区分是切换扫描列还是进行按键检测。
PE2 ,PE3,PE4, PE5 键盘检测口,上拉输入,低电平有效
PC5,PC2,PC3,PE6 是扫描列,初始化高电平,低电平扫描
#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "Key.h"
void Key_scan(void);
__IO uint32_t Key_count=0;//扫描计数器
__IO uint32_t Key_flag=0;//按键标志
__IO uint32_t Key_end=0; //最终按键扫描结果
__IO uint32_t Key_head=0; //缓冲队列头指针
__IO uint32_t Key_tail=2; //缓冲队列尾指针
__IO uint32_t Key_buf[2]={0,0}; //按键缓冲区
enum Key {NONE,K1,K2,K3,K4,K5,K6,K7,K8,K9,K10,K11,K12,K13,K14,K15,K16}Key_num; //单次按键枚举值
void Key_scan(void)
{
if(Key_count>=8) //偶数扫描,奇数检测按键,间隔10MS
{
Key_count=0;
}
else
{
if(Key_flag==1)
{
Key_count=Key_count; //维持扫描口低电平有效
}
else
{
Key_count++; //扫描下一列
}
}
switch(Key_count)
{
case 0:GPIOC->BRR=GPIO_Pin_5;//置0扫描
break;
case 2:GPIOC->BRR=GPIO_Pin_2;//置0扫描
break;
case 4:GPIOC->BRR=GPIO_Pin_3;//置0扫描
break;
case 6:GPIOE->BRR=GPIO_Pin_6;//置0扫描
break;
case 1: if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==Bit_RESET) //奇数检测IO口,低位为按键按下
{
Key_num=K1; //按键值
Key_flag=1; //按键标志有效
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==Bit_RESET)
{
Key_num=K4;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==Bit_RESET)
{
Key_num=K7;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_5)==Bit_RESET)
{
Key_num=K10;
Key_flag=1;
}
else
{
Key_num=NONE;
Key_flag=0;
GPIOC->BSRR=GPIO_Pin_5;//无按键按下对应扫描端置1复位,准备扫描下一列
}
break;
case 3: if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==Bit_RESET)
{
Key_num=K2;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==Bit_RESET)
{
Key_num=K5;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==Bit_RESET)
{
Key_num=K8;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_5)==Bit_RESET)
{
Key_num=K11;
Key_flag=1;
}
else
{
Key_num=NONE;
Key_flag=0;
GPIOC->BSRR=GPIO_Pin_2;//无按键按下对应扫描端置1复位,准备扫描下一列
}
break;
case 5: if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==Bit_RESET)
{
Key_num=K3;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==Bit_RESET)
{
Key_num=K6;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==Bit_RESET)
{
Key_num=K9;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_5)==Bit_RESET)
{
Key_num=K12;
Key_flag=1;
}
else
{
Key_num=NONE;
Key_flag=0;
GPIOC->BSRR=GPIO_Pin_3;//无按键按下对应扫描端置1复位,准备扫描下一列
}
break;
case 7: if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==Bit_RESET)
{
Key_num=K15;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==Bit_RESET)
{
Key_num=K16;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==Bit_RESET)
{
Key_num=K14;
Key_flag=1;
}
else if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_5)==Bit_RESET)
{
Key_num=K13;
Key_flag=1;
}
else
{
Key_num=NONE;
Key_flag=0;
GPIOE->BSRR=GPIO_Pin_6;
}
break;
default:
break;
}
if(Key_head<Key_tail)
{
Key_buf[Key_head]=Key_num; //缓冲未满一次,写入单次按键值
Key_head++;
}
else
{
Key_head=0; //缓冲写满,判断按键
if((Key_buf[0]==Key_buf[1]))
{
Key_end=Key_num; //满足消抖,按键输出
}
}
}
|
-
|