前面的cubemx配置都和定时中断的一样,详情请看上文,这篇我们主要写按键相关的代码。
前面的外部中断的按键,还有直接写的按键函数都不适用于比赛,各有不同缺点。在比赛中按键又是个很重要的外设,那如何实现按键呢,请看以下的内容。
首先,新建两个文件(key.c 和 key.h)用于放置关于按键的函数。
前面我们将定时器设置为每隔10ms进行一次中断。考虑到按键抖动问题。如果连着两次10ms的判断都是低电平,就会有真正的按键被按下。
按键短按
按键读取函数
//low return 0
//high return 1
uint8_t key_read()
{
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0) return 1;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0) return 2;
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0) return 3;
else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0) return 4;
else return 0;
}
按键服务函数
struct Bkeys
{
uint8_t age;
uint8_t flag;
}
struct Bkeys bkey[5]={0,0};
void key_serv()
{
uint8_t key_sta=key_read();
if(key_sta!=0)
{
bkey[key_sta].age++;
if(bkey[key.sta].age>1) bkey[key_sta].flag=1;
}
else
{
for(int i=0;i<5;++)
bkey[i].age=0;
}
}
中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
key_serv();
}
my_main.c
extern struct Bkeys bkey[];
void loop()
{
if(bkey[1].flag==1)
{
sprintf(text," KEY1 DOWN ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[1].flag=0;
}
if(bkey[2].flag==1)
{
sprintf(text," KEY2 DOWN ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[2].flag=0;
}
}
按键长按
按键服务函数
struct Bkeys
{
uint8_t age;
uint8_t short_flag;
uint8_t long_flag;
uint8_t press;
}
struct Bkeys bkey[5]={0,0};
void key_serv_long()
{
uint8_t key_sta=key_read();
if(key_sta!=0)
{
bkey[key_sta].age++;
if(bkey[key.sta].age>1) bkey[key_sta].press=1;
}
else
{
for(int i=0;i<5;++)
{
if(bkey[i].press==1&&bkey[i].long_flag=0) bkey[i].short_flag=1;
bkey[i].press=0;
bkey[i].age=0;
bkey[i].long_flag=0;
}
}
if(bkey[key.sta].age>69) bkey[key_sta].long_flag=1;
}
中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM6)
key_serv_long();
}
my_main.c
实现步进自增功能
extern struct Bkeys bkey[];
void loop()
{
static uint16_t temp;
if(bkey[1].short_flag==1)
{
sprintf(text," KEY1 DOWN ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[1].short_flag=0;
}
if(bkey[2].short_flag==1)
{
sprintf(text," KEY2 DOWN ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[2].short_flag=0;
}
if(bkey[1].long_flag==1)
{
sprintf(text," KEY1 LONG ! %d ",temp);
LCD_DisplayStringLine(Line8,(uint8_t*)text);
temp++;
}
if(bkey[2].long_flag==1)
{
sprintf(text," KEY2 LONG ! %d ",temp);
LCD_DisplayStringLine(Line8,(uint8_t*)text);
temp++;
}
}
实现按超过2s后松开
按键服务函数
struct Bkeys
{
uint8_t age;
uint8_t short_flag;
uint8_t long_flag;
uint8_t press;
}
struct Bkeys bkey[5]={0,0};
void key_serv_long()
{
uint8_t key_sta=key_read();
if(key_sta!=0)
{
bkey[key_sta].age++;
if(bkey[key.sta].age>1) bkey[key_sta].press=1;
}
else
{
for(int i=0;i<5;++)
{
if(bkey[key.sta].age>69) bkey[key_sta].long_flag=1;
if(bkey[i].press==1&&bkey[i].long_flag=0) bkey[i].short_flag=1;
bkey[i].press=0;
bkey[i].age=0;
}
}
}
extern struct Bkeys bkey[];
void loop()
{
static uint16_t temp;
if(bkey[1].short_flag==1)
{
sprintf(text," KEY1 DOWN ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[1].short_flag=0;
}
if(bkey[2].short_flag==1)
{
sprintf(text," KEY2 DOWN ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[2].short_flag=0;
}
if(bkey[1].long_flag==1)
{
sprintf(text," KEY1 LONG ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[1].long_flag=0;
}
if(bkey[2].long_flag==1)
{
sprintf(text," KEY2 LONG ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[2].long_flag=0;
}
}
按键双击
按键服务函数
struct Bkeys
{
uint8_t age;
uint8_t short_flag;
uint8_t long_flag;
uint8_t press;
uint8_t double_ageEN;
uint8_t double_age;
uint8_t double_flag;
}
struct Bkeys bkey[5]={0,0};
void key_serv_double()
{
uint8_t key_sta=key_read();
if(key_sta!=0)
{
bkey[key_sta].age++;
if(bkey[key.sta].age>1) bkey[key_sta].press=1;
}
else
{
for(int i=0;i<5;++)
{
if(bkey[i].double_ageEN=1&&bkey[i].press==1)
{
bkey[i].double_flag=1;
bkey[i].double_age=0;
bkey[i].double_ageEN=0;
}
if(bkey[i].press==1&&bkey[i].long_flag==0) bkey[i].double_ageEN=1;
if(bkey[i].double_ageEN==1) bkey[i].double_age++;
if(bkey[i].double_ageEN==1&&bkey[i].double_age>20)
{
bkey[i].short_flag=1;
bkey[i].double_age=0;
bkey[i].double_ageEN=0;
}
bkey[i].press=0;
bkey[i].age=0;
}
}
}
中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM6)
key_serv_double();
}
my_main.c
extern struct Bkeys bkey[];
void loop()
{
static uint16_t temp;
if(bkey[1].short_flag==1)
{
sprintf(text," KEY1 DOWN ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[1].short_flag=0;
}
if(bkey[2].short_flag==1)
{
sprintf(text," KEY2 DOWN ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[2].short_flag=0;
}
if(bkey[1].long_flag==1)
{
sprintf(text," KEY1 LONG ! %d ",temp);
LCD_DisplayStringLine(Line8,(uint8_t*)text);
temp++;
}
if(bkey[2].long_flag==1)
{
sprintf(text," KEY2 LONG ! %d ",temp);
LCD_DisplayStringLine(Line8,(uint8_t*)text);
temp++;
}
if(bkey[1].double_flag==1)
{
sprintf(text," KEY1 DOUBLE ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[1].double_flag=0;
}
if(bkey[2].double_flag==1)
{
sprintf(text," KEY2 DOUBLE ! ");
LCD_DisplayStringLine(Line8,(uint8_t*)text);
bkey[2].double_flag=0;
}
}