IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 基于stm32f4的按键检测 -> 正文阅读

[嵌入式]基于stm32f4的按键检测

基于stm32f4的按键检测

所谓按键检测,即是检测按键是长按,还是短按。(长按、短按由按键的时间的长短来衡量)通过查阅相关资料,找到了两种比较好理解的按键检测方法。一种是通过输入捕获的方式检测按键按下前后的电平转换时间,来判断按键是长按还是短按;另外一种是通过将按键扫描函数放在定时器中断里,检测按键按下前后的电平转换时间,进而判断按键状态 。但总的来说,以上这两种方式所用的方法是类似的,即通过检测电平转换时间的长短,从而确定按键是长按还是短按。
第一种方式对应部分源码如下:

    long long temp=0;
 	temp=TIM5CH1_CAPTURE_STA&0X3F; 
	temp*=0XFFFFFFFF;		 		         //溢出时间总和
	temp+=TIM5CH1_CAPTURE_VAL;		   //得到总的高电平时间
	printf("HIGH:%lld us\r\n",temp); //打印总的高点平时间
	if(temp>=500000)//长按0.5s
    {
           switch_flag=1;
    }
   else if(temp>=100000)//短按至少0.1s
    {
          switch_flag=0;
    }

第二种方式对应部分源码如下:

    //定时器3中断服务函数
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
	{
		Key_scan();
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}

//Key_scan函数
void Key_scan(void)
{
	//1 表示高电平,0表示低电平。低电平时按下	
	if(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) )//按键按下 记录按下的时间	
	{
		delay_ms(20);//消抖时间,后加
		count++;
	}
	else //按键松开 计数值清零并返回按下的时间值
	{
		if(count>100)//按下经过1s  10*10ms=100ms
		{
    		//长按
			switch_flag= 1;
		}
		else if(count>10 && count <100)//表示超过10ms
		{
			//短按
			switch_flag= 0;
		}
		else
		{	
			delay_ms(20);//消抖时间,后加
		}
		count=0;
	}
...
}

而在判断出按键状态之后,可以简单地实现检测单个按键连续两次按下的相关状态。如一个按键短按一次,长按一次,控制LED翻转;随后再短按一次,长按一次,控制LED翻转。部分代码如下;

unsigned int switch_flag=1;//初始状态设置为1,防止第一次长按时误判断
unsigned int switch_flag_old=1;//初始状态设置为1,防止第一次长按时误判断
unsigned int switch_flag_state=0;
//以下语句放在key_scan函数中,上接...
static unsigned int switch_flag_old=1;//利用static变量,防止第一次长按时,误判断		
	if((switch_flag==1)&&(switch_flag_old==0)) //
	{
		if(switch_flag_state==0)//区分swtich开关状态,判断上一次开关的状态
			switch_on();
			else
			switch_off(); 
	}
switch_flag_old=switch_flag;//表示前一个状态,到这里
//switch闭合函数 
void switch_on(void)
{
	LED1=!LED1;//DS1翻转
	switch_flag_state=1;
}
//switch断开函数
void switch_off(void)
{
	LED1=!LED1;//DS1翻转
	switch_flag_state=0;
}

在实际调试过程中,参照了之前产生上升沿波形的例子。而对switch_flag,及switch_flag_old的初值设置为1,可以避免在第一次按键长按时,就会进入按键判断语句,从而使功能有误。完整代码已通过正点原子stm32f407开发板检测。欢迎各位指正。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-05-19 12:00:56  更:2022-05-19 12:01:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:34:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码