蓝桥杯物联网竞赛_STM32L071_18_长短按键检测

长短按键的检测是国赛题里面遇到的,省赛没出过有两种实方法

定时器配置:

定时器的话要比delay准确,其中tim7定时器的准度最高


定时器预分配配置32 - 1,计数周期是10000 - 1这样做那么32MHZ/32也就是一秒钟记录10^6的数,计数周期配置10 ^ 4也就是说一个周期花费10 ^ 4/10 ^6秒也就是10ms

c 复制代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){  // 10ms
	// OLED_ShowString(0, "KEY)");
	COUNTNUMBER ++;
}

1、普通按键实现:

普通按键我用的是矩阵按键模块的B1按键测试的

ROW1与ROW2配置为输入模式上拉,COLUMN1配置输出模式

c 复制代码
void Function_KeyCheck(){
  HAL_GPIO_WritePin(COLUMN1_GPIO_Port, COLUMN1_Pin, GPIO_PIN_RESET);
	if(HAL_GPIO_ReadPin(ROW1_GPIO_Port, ROW1_Pin) == 0){  // 按键按下
		HAL_TIM_Base_Start_IT(&htim7);
		while(HAL_GPIO_ReadPin(ROW1_GPIO_Port, ROW1_Pin) == 0);  // 等待定时器关闭
		HAL_TIM_Base_Stop_IT(&htim7);
		if(COUNTNUMBER <= 100) KEYTIMEFLAG = 0;
		else KEYTIMEFLAG = 1;
		PRESSTIME = (float) COUNTNUMBER * 1.0 / 100;
		COUNTNUMBER = 0;
	}
 
	HAL_GPIO_WritePin(COLUMN1_GPIO_Port, COLUMN1_Pin, GPIO_PIN_SET);
	
}

2、中断按键实现:


中断按键设置成上升沿和下降沿都会触发的模式,这样人按下按键就是下降沿这时候开定时器,松开就是上升沿,关定时器

c 复制代码
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){  // 中断按键
	
	if(!HAL_GPIO_ReadPin(USER_Key_GPIO_Port, USER_Key_Pin)){  // 下降电平开启定时器
		HAL_TIM_Base_Start_IT(&htim7);
	}else{  // 上升电平关闭定时器并检测时间
		if(COUNTNUMBER <= 100) KEYTIMEFLAG = 0;
		else KEYTIMEFLAG = 1;
		PRESSTIME = (float) COUNTNUMBER * 1.0 / 100;
		COUNTNUMBER = 0;
		HAL_TIM_Base_Stop_IT(&htim7);
	}
}

完整代码:

Function.c

c 复制代码
#include "Function.h"
#include "main.h"
#include "oled.h"
#include "i2c.h"
#include <stdio.h>
#include "tim.h"

unsigned char KEYFLAG = 0;
unsigned char ARRAY[20];
char* LONGKEY = "long key press";
char* SHORTKEY = "short key press";
unsigned char KEYTIMEFLAG = 2;
float PRESSTIME = 0;

uint32_t COUNTNUMBER = 0;  // 记录时间,这个区间必须要足够大

void OLED_Write(unsigned char type, unsigned char data){
  unsigned char WriteData[2];
	WriteData[0] = type;
	WriteData[1] = data;
	HAL_I2C_Master_Transmit(&hi2c3, 0x78, WriteData, 2, 0xff);
}
void Function_OledInit(unsigned char ms){
  HAL_GPIO_WritePin(OLED_Power_GPIO_Port, OLED_Power_Pin, GPIO_PIN_RESET);
	HAL_Delay(ms);
	OLED_Init();
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){  // 10ms
	// OLED_ShowString(0, "KEY)");
	COUNTNUMBER ++;
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){  // 中断按键
	
	if(!HAL_GPIO_ReadPin(USER_Key_GPIO_Port, USER_Key_Pin)){  // 下降电平开启定时器
		HAL_TIM_Base_Start_IT(&htim7);
	}else{  // 上升电平关闭定时器并检测时间
		if(COUNTNUMBER <= 100) KEYTIMEFLAG = 0;
		else KEYTIMEFLAG = 1;
		PRESSTIME = (float) COUNTNUMBER * 1.0 / 100;
		COUNTNUMBER = 0;
		HAL_TIM_Base_Stop_IT(&htim7);
	}
	
}


void Function_KeyCheck(){
  HAL_GPIO_WritePin(COLUMN1_GPIO_Port, COLUMN1_Pin, GPIO_PIN_RESET);
	if(HAL_GPIO_ReadPin(ROW1_GPIO_Port, ROW1_Pin) == 0){  // 按键按下
		HAL_TIM_Base_Start_IT(&htim7);
		while(HAL_GPIO_ReadPin(ROW1_GPIO_Port, ROW1_Pin) == 0);  // 等待定时器关闭
		HAL_TIM_Base_Stop_IT(&htim7);
		if(COUNTNUMBER <= 100) KEYTIMEFLAG = 0;
		else KEYTIMEFLAG = 1;
		PRESSTIME = (float) COUNTNUMBER * 1.0 / 100;
		COUNTNUMBER = 0;
	}
 
	HAL_GPIO_WritePin(COLUMN1_GPIO_Port, COLUMN1_Pin, GPIO_PIN_SET);
	
}

void Function_MyMain(){
	 Function_KeyCheck();
	 if(KEYTIMEFLAG != 2){
 
		 sprintf((char* )ARRAY, "%.2f s", PRESSTIME);
		 if(KEYTIMEFLAG == 0){
			 OLED_ShowString(0, (unsigned char* )SHORTKEY);
		 }else if(KEYTIMEFLAG == 1){
		   OLED_ShowString(0, (unsigned char* )LONGKEY);
			  
		 }
		 OLED_ShowString(2, ARRAY);
		 KEYTIMEFLAG = 2;
	 }
}

Function.h

c 复制代码
#ifndef __FUNCTION_H__
#define __FUNCTION_H__
#include "main.h"

void OLED_Write(unsigned char type, unsigned char data);
void Function_OledInit(unsigned char ms);
void Function_MyMain();
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

#endif

效果:


相关推荐
DuHz5 小时前
论文阅读——Edge Impulse:面向微型机器学习的MLOps平台
论文阅读·人工智能·物联网·算法·机器学习·edge·边缘计算
芯联智造5 小时前
【stm32简单外设篇】- 单路 TTP223 电容式触摸传感器
c语言·stm32·单片机·嵌入式硬件
张工在路上6 小时前
(深入探讨句柄泄漏、内存泄漏检测工具)我将分析可能导致内存泄漏(包括托管内存和非托管内存,如句柄泄漏)
stm32·单片机·嵌入式硬件
网络安全那些事7 小时前
Node-RED 物联网实践系列(4.1):核心节点精讲(Inject/Debug/Change/Switch/Function)
物联网·低代码·数据采集·工业互联网·nodered
数据库学啊7 小时前
物联网(IoT)项目,时序数据库选型推荐哪个?
数据库·物联网·时序数据库
DolphinDB智臾科技8 小时前
工业物联网时序数据库选型指南:DolphinDB vs InfluxDB vs TimescaleDB
数据库·物联网·时序数据库
hdktq8 小时前
新建HAL版本MDK工程(正点原子版本)
stm32
良木生香10 小时前
【程序设计】P8772 [蓝桥杯 2022 省 A] 求和
c语言·算法·职场和发展·蓝桥杯
沉在嵌入式的鱼12 小时前
STM32--GY906体温检测传感器
stm32·单片机·嵌入式硬件·gy906·体温检测
2401_8534482312 小时前
Spieed micarray开发介绍
stm32·sk9822·sipeed mic