嵌入式蓝桥杯学习6 定时中断按键(短按 长按 双击)

news/2024/12/12 14:33:44/

前面的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;}
}


http://www.ppmy.cn/news/1554521.html

相关文章

【Android】车芯 | 使用HTP运行设备端模型

首先,确保运行在设备的模型制作过程以及host端验证已完成啦。模型制作过程可参考:【qualcomm】QNN SDK的下载以及运行在设备端的模型制作-CSDN博客 本文以之前生成的Resnet18_quantized.bin作为测试模型。 1 新建文件夹/data/test

Socks5机房代理IP的测试与挑选指南

选择合适的代理IP不仅能够提升您的网络体验&#xff0c;还能够保护您的个人信息和数据安全&#xff0c;让您更加安心地畅游互联网世界。因此如何测试和挑选合适的代理IP就显得尤为重要。本文将为您详细介绍测试和挑选方法。 1. 确定测试指标 在测试和挑选之前&#xff0c;首先…

单片机:实现贪吃蛇(附带源码)

单片机实现贪吃蛇游戏是一个较为复杂的项目&#xff0c;涉及到硬件控制、程序设计、图形显示、输入处理等方面。这里我们以基于8051单片机为例&#xff0c;详细介绍如何通过硬件和软件来实现一个简单的贪吃蛇游戏。为了让解释更加清晰&#xff0c;我们将逐步分析贪吃蛇的游戏逻…

RPO: Read-only Prompt Optimization for Vision-Language Few-shot Learning

文章汇总 想解决的问题 对CoOp的改进CoCoOp尽管提升了性能&#xff0c;但却增加了方差&#xff08;模型的准确率波动性较大&#xff09;。 模型的框架 一眼看去&#xff0c;跟maple很像(maple跟这篇文章都是2023年发表的)&#xff0c;但maple的视觉提示是由文本提示经过全连接…

深度学习笔记之BERT(五)TinyBERT

深度学习笔记之TinyBERT 引言回顾&#xff1a;DistilBERT模型TinyBERT模型结构TinyBERT模型策略Transformer层蒸馏嵌入层蒸馏预测层蒸馏 TinyBERT模型的训练效果展示 引言 上一节介绍了 DistilBERT \text{DistilBERT} DistilBERT模型&#xff0c;本节将继续介绍优化性更强的知…

操作系统Lesson12 - 交互式和实施系统调度

文章目录 交互系统中的调度轮询调度优先级调度静态分配动态分配彩票调度多级反馈队列MLFQ公平分享调度 实时调度线程调度 先来先服务 用于非抢占式调度算法。 基于时间片 -> 抢占式 -> 绝对非抢占 磁盘任务放到内存 -> 作业调度 内存任务放到CPU -> 进程调度 缺…

Edge SCDN的独特优势有哪些?

强大的边缘计算能力 Edge SCDN&#xff08;边缘安全加速&#xff09;是酷盾安全推出的边缘集分布式 DDoS 防护、CC 防护、WAF 防护、BOT 行为分析为一体的安全加速解决方案。通过边缘缓存技术&#xff0c;智能调度使用户就近获取所需内容&#xff0c;为用户提供稳定快速的访问…

Github 2024-12-01 开源项目月报 Top20

根据Github Trendings的统计,本月(2024-12-01统计)共有20个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10TypeScript项目9Go项目2HTML项目1Shell项目1Jupyter Notebook项目1屏幕截图转代码应用 创建周期:114 天开发语言:TypeScript, Py…