一、硬件介绍
正点原子战舰开发板
LED0-----PB5 LED1-----PE5 KEY0-----PA4
二、实现目的
开机LED0、LED1均熄灭 单击KEY0,LED0点亮、LED1熄灭 双击KEY0,LED0熄灭、LED1点亮 长按,LED0,LED1均熄灭
三、设计思路
1、两个LED对应的IO设置为推挽输出,高电平,保证开机时灯处于熄灭状态 2、按键KEY0设置为上拉输入,按下后为低电平,松手为高电平 3、单击、双击、长按的区别示意图如下 首先需要区分单击和长按,可以看到长按就是按下的时间比较长的单击。如下图可以看到,如果检测到低电平的时间超过S3那么则是长按,否则就是单击。 单击和双击的区别,松开后,在一定的时间内是否再次检测到低电平。如下图,在松开手后如果在D2内检测到低电平,那么便是双击。否则便是单击。
单击表现出来的效果为高、低、高。即按下后低电平持续时间小于1s为单击 双击表现形式为高、低、高、低、高,即两次单击,且两次单击之间间隔要小于200ms 长按表现形式为高、低、高。即按下后低电平持续时间长于1s为长按
四、代码简介
主要是五个文件
LED源文件和头文件 led.c
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_5);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
}
led.h
#define LED0 PBout(5)
#define LED1 PEout(5)
void LED_Init(void);
KEY源文件和头文件 key.c
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
key.h
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)
void KEY_Init(void);
主函数main.c main.c
int main(void)
{
int a=0,b=0,c=0;
delay_init();
LED_Init();
KEY_Init();
LED0=1;
LED1=1;
while(1)
{
if(KEY0==0)
{
delay_ms(10);
if(KEY0==0)
{
while((KEY0==0)&&c<100)
{
c++;
delay_ms(10);
}
if(c>=100)
{
LED0=1;
LED1=1;
while(KEY0==0);
}
else
{
for(b=0;b<10;b++)
{
delay_ms(20);
if(KEY0==0)
{
a=1;
LED0=0;
LED1=0;
while(KEY0==0);
}
}
if(a==0)
{
LED0=0;
LED1=1;
}
}
a=0;
c=0;
}
}
}
}
这个是通过扫描和循环的方式进行按键判断,代码参考的洋桃电子,没有用到定时器和中断,代码验证过,可以参考。 通过c的值,来判断操作是单击还是长按;通过a的值,来判断是单击还是双击。 通过改变两个自加次数,来改变双击之间时间间隔以及长按判定等的时间参数。
|