[蓝桥杯国赛]按键双击/多击触发

博客介绍了在单片机中实现按键双击和三击功能的思路,类似按键长按,在key_state_2里判断未松开时计数,设置标志位统计按键次数,还给出了程序示例,如key_press=0x77为长按部分,key_press=0xee为双击部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路同按键长按,在key_state_2里判断如何没有松开的时候加一,如果我设置一个标志让按键按下一次后标志位置1,这样我就能统计按下了几次,这样就可以实现双击和三击的功能,程序如下,key_press=0x77是长按部分,key_press=0xee是双击部分

case KEY_STATE_2:
if(key_press == NO_KEY)
{
	key_state=KEY_STATE_0;
}
else
{
	if(key_press==0x77)
	{
		sustain_press_time++;
		if(sustain_press_time==400)
		{
			sustain_press_time=0;
			led_flag=1;
		}	
	}
	if(key_press==0xee)
	{
		if(key19_one_flag==1)
		{
			key19_one_flag=0;
			sustain_press_time_ee++;
			if(sustain_press_time_ee==2)
			{
				sustain_press_time_ee=0;
				led2_flag=1;
			}
		}
	}
}
break;

### 蓝桥杯单片机按键双击功能实现 为了实现在蓝桥杯中的单片机按键双击功能,可以基于已有的代码框架进行扩展。具体来说,在 `key()` 函数中加入检测逻辑来识别单次点双击事件。 #### 检测原理 当按下按钮时记录时间戳并启动定时器;释放后再次按压的时间间隔小于设定阈值则视为一次双击操作[^1]。 #### 修改后的主循环结构 原有程序已经包含了无限循环用于持续监测输入状态变化: ```c void main() { Timer0_Init(); Timer1_Init(); close(); while (1) { key(); // 处理按键扫描 keyrun(); // 执行相应动作 LED_run(); // 控制LED显示 smg_run(); // 驱动数码管刷新 } } ``` #### 新增的按键处理函数定义 下面是一个可能版本的关键部分——`key()` 的改进版,它能够区分单双击行为: ```c #include <reg52.h> sbit KEY = P3^2; // 定义按键连接端口位 unsigned char click_count; unsigned int last_press_time; #define DEBOUNCE_DELAY 20 // 去抖延时常量(ms) #define DOUBLE_CLICK_TIME 300 // 判断两次快速连续点的最大允许间隔(ms) // 初始化全局变量 void init_key(void){ click_count = 0; } // 获取当前系统毫秒级计数值(假设由Timer0提供) extern unsigned long get_tick_ms(void); // 键盘去抖子程序 void debounce_delay(unsigned int ms){ unsigned int i, j; for(i=ms;i>0;i--) for(j=11;j>0;j--); } // 主要修改处:增加对双击的支持 void key(){ static bit is_pressed = 0; if(KEY == 0 && !is_pressed){ // 当前未被按下但此时变为低电平表示触发下降沿即按下 is_pressed = 1; // 等待一段时间消除机械开关带来的噪声影响 debounce_delay(DEBOUNCE_DELAY); if(KEY == 0){ // 如果仍然保持低电平,则确认确实发生了有效按下 unsigned long current_time = get_tick_ms(); if((current_time - last_press_time) <= DOUBLE_CLICK_TIME){ ++click_count; if(click_count >= 2){ // 这里放置响应双击的具体业务逻辑... // 清除计数以便后续正常工作 click_count = 0; } }else{ click_count = 1; // 记录首次点次数重置为一 // 更新最后一次成功读取到高->低转换发生时刻作为新的起点 last_press_time = current_time; } // 继续等待直到松开为止再继续其他流程 while(!KEY); } }elseif(KEY != 0 && is_pressed){ // 上升沿到来说明刚刚结束了一轮完整的按压过程 is_pressed = 0; } } ``` 此段代码通过引入额外的状态标志以及时间戳比较机制实现了较为可靠的双击判断算法,并且保留了原有的硬件接口配置不变以兼容原项目需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值