当前位置: 首页 > backend >正文

蓝桥杯嵌入式按键长短按移植

蓝桥杯嵌入式按键长短按移植

文章目录

  • 蓝桥杯嵌入式按键长短按移植
    • 1、外设占用,基本定时器1个,配置为10ms中断
    • 2、按键代码

1、外设占用,基本定时器1个,配置为10ms中断

初始化后,打开中断。

HAL_TIM_Base_Start_IT(&htim4);//打开定时器中断

2、按键代码

key.c:

#include "key.h"
#include "oled.h"struct keys g_key[4] = {0,0,0,0};/*** @brief 按键扫描函数,需要10ms执行一次* 
*/
void key_scan(void)
{//读取本次扫描电平状态g_key[0].state_pin = HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin);g_key[1].state_pin = HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin);g_key[2].state_pin = HAL_GPIO_ReadPin(KEY3_GPIO_Port,KEY3_Pin);g_key[3].state_pin = HAL_GPIO_ReadPin(KEY4_GPIO_Port,KEY4_Pin);//轮询按键消抖for(int i=0;i<4;i++){switch(g_key[i].state_step){case 0://首次按下{if(g_key[i].state_pin == 0){g_key[i].state_step = 1;    //跳转到消抖状态g_key[i].time_press = 0;    //清零计时}}break;case 1://10ms后按键仍按下,说明电平已稳定,完成消抖{if(g_key[i].state_pin == 0){// g_key[i].flag_press = 1;    //记录短按生效g_key[i].state_step = 2;    //跳转到松手检测}elseg_key[i].state_step = 0;    //否则视为抖动,重新检测}break;case 2://读取到松手,本次扫描结束{if(g_key[i].state_pin == 1)//松手{if(g_key[i].time_press < 100)//小于1s视为短按{g_key[i].flag_press = 1;//短按松手生效}else if(g_key[i].time_press >= 100)//大于1s视为长按{g_key[i].flag_press_long = 1;//长按松手生效}g_key[i].state_step = 0;        //回到最初状态}else{g_key[i].time_press++;//未松手就计时
//                    if(g_key[i].time_press >= 100)
//                        g_key[i].flag_press_long = 1;//长按未松手生效,放在这里会由bug,按完不松手会与key_proc里的清零一直冲突,相当于长按一直生效}}break;}}
}/*** @brief 按键动作处理函数,响应按键动作* */
void key_proc(void)
{static uint8_t a = 0;static uint8_t b = 0;if(g_key[0].flag_press == 1)//按键1动作处理{OLED_ShowNum(0,0,a++,3,16,1);OLED_Refresh();g_key[0].flag_press = 0;//记住用完后一定要清零,才能继续使用}if(g_key[0].flag_press_long == 1)//按键1动作处理{HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);g_key[0].flag_press_long = 0;//记住用完后一定要清零,才能继续使用}if(g_key[1].flag_press == 1)//按键2动作处理{OLED_ShowNum(0,16,b++,3,16,1);OLED_Refresh();g_key[1].flag_press = 0;//记住用完后一定要清零,才能继续使用}if(g_key[1].flag_press_long == 1)//按键2动作处理{HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);g_key[1].flag_press_long = 0;//记住用完后一定要清零,才能继续使用}
}

key.h:

#ifndef __KEY_H
#define __KEY_H#include "main.h"struct keys
{uint8_t state_step;       //判断进程uint8_t state_pin;        //按键电平状态uint8_t flag_press;       //按键按下标志位uint16_t time_press;      //记录按下时间*10msuint8_t flag_press_long;  //长按标志位
};extern struct keys g_key[];void key_scan(void);
void key_proc(void);
#endif

定时器中断:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM4)//10ms按键扫描{key_scan();}
}

main.c:

while (1){key_proc();}
http://www.xdnf.cn/news/4105.html

相关文章:

  • LeetCode:链表的中间结点
  • Linux的时间同步
  • HTTP/HTTPS协议(请求响应模型、状态码)
  • 1247: 彩色的棋子(chess)
  • 《Spring 中 @Autowired 注解详解》
  • 2023年408真题及答案
  • 读《人生道路的选择》有感
  • Day11 训练
  • 30天开发操作系统 第27天 -- LDT与库
  • Gateway网关:路由和鉴权
  • LeetCode 238:除自身以外数组的乘积(Java实现)
  • CRM客户关系管理系统高级版客户管理销售管理合同管理数据分析TP6.0框架源码
  • 阿里云服务器深度科普:技术架构与未来图景
  • kdump详解
  • 基于SRS实现流媒体服务器(最简单的流媒体服务器)
  • 【外围电路】0.介绍
  • react路由使用方法
  • 【ArUco boards】标定板检测
  • 《架构安全原则》解锁架构安全新密码
  • c++进阶——AVL树主要功能的模拟实现(附带旋转操作讲解)
  • ADK 第四篇 Runner 执行器
  • 把Android设备变成“国标摄像头”:GB28181移动终端实战接入指南
  • 博图V20编译报错:备不受支持,无法编译。请更改为受支持的设备。
  • C++初学者的入门指南
  • [Windows] 批量修改文件/文件夹时间戳工具 NewFileTime 7.71
  • VUE3报错 ReferenceError: Cannot access ‘openInit‘ before initialization
  • 【Qt】配置环境变量
  • educoder平台课-Python程序设计-8.文件
  • 价格识别策略思路
  • 第16章 监控和排除日志记录错误