蓝桥杯单片机独立按键扫描程序

本文介绍了一种高效的独立按键处理方法,仅用三行代码就能有效解决按键抖动及单次与长按识别问题。通过分析代码中的关键变量Trg和Cont,以及它们在不同按键状态下的作用,揭示了其巧妙的设计思路。

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

最近自己在做单片机的东西,准备参加比赛,偶然发现了独立按键的神助攻——三行搞定独立按键,看到网上很多描述的不清晰,自己又花时间整理了一下,话不多说先上代码:

void Key_Read(void)
  {
   ReadData=KeyPort^0xff;
  Trg=ReadData&(ReadData^Cont);
  Cont=ReadData;
  }

千万不要小瞧了这三行代码,威力可是相当的大啊。
首先说一下这几个小符号:异或"^",与"&",或"||",非"~"。在这几行代码中,Trg(Triger) 代表的是触发,Cont(continue)代表的是连续、继续。
对于独立按键或者矩阵键盘,我们要解决的问题无非就是1.按键未按下时;2.按键按下时;3.按键一直按下时;4.按键弹起复原,这四种状态下分别对应的要发生的情况。那么对于这几行代码我们倒着去分析,今天不去想它怎么写出来的,我们想想为什么要这要写,这样写的巧妙之处在哪。
我们假设按键K1对应的端口为P3^0,可以得到如下图所示的关系(具体过程按照代码推导一下就出来了):
在这里插入图片描述
四种情形其实只有三种,无按下时与按下后复原的情况相同,我们只要区别开按键单次按下和长按的区别即可,此时再去看Trg与Cont的区别是不是更为明显了呢?Trg(Triger) 代表的是单次触发,Cont(continue)代表的是连续按下。只有在长按时,Trg为0,其余均为0X01,可以有效的对两种情况进行区分。
从本质上来讲,这一个扫描函数就是一直在循环往复的运行,大约是每10ms进行一次扫描,可以从以下时间轴来看:对于扫描的周期我假定为10ms
就这样,通过这个10ms的周期扫描以及Trg与Cont之间的关系,巧妙的解决了按键的抖动问题与单词按键和长时间按键的问题

在这里插入图片描述

### 蓝桥杯单片机按键程序设计方案与示例代码 #### 一、按键程序设计概述 在蓝桥杯竞赛中,单片机按键程序的设计通常涉及硬件电路连接、中断处理机制以及软件逻辑实现。按键的功能可以通过简单的轮询方式或者更高效的中断方式进行检测[^1]。 #### 二、按键程序的基础读写操作 以下是基于 AT24C02 的按键触发基础读写操作的示例代码: ```c #include <reg52.h> sbit KEY = P3^0; // 定义按键引脚 void delay(unsigned int time) { while (time--) { ; } } // 按键扫描函数 unsigned char key_scan() { unsigned char state; KEY = 1; // 上拉电平 delay(10000); // 去抖动延迟 state = KEY; // 获取当前状态 if (!state) { // 如果按键按下 delay(10000); // 再次去抖动 if (!KEY) { // 确认按键确实被按下 return 1; // 返回按键按下的标志 } } return 0; // 否则返回未按下 } ``` 上述代码实现了基本的按键扫描功能,并加入了必要的去抖动措施以提高稳定性。 #### 三、按键触发的应用场景 对于更加复杂的按键控制需求,可以引入滴答定时器来管理按键的状态变化。这种方法能够有效减少 CPU 的占用率并提升响应速度[^3]。 以下是一个利用滴答定时器实现 LED 切换的例子,适用于按键触发场景: ```c __IO uint32_t buttonTick = 0; u8 button_state = 0; void Button_Process(void) { static u8 last_button_state = 1; // 记录上一次按钮状态 if (P3_0 != last_button_state) { // 检测到状态改变 delay(10000); // 去抖动 if (P3_0 != last_button_state) { // 再次确认 if (!P3_0) { // 按键按下事件 buttonTick = uwTick; // 更新时间戳 button_state ^= 1; // 取反状态 } last_button_state = P3_0; // 更新记录 } } if ((uwTick - buttonTick >= 100) && !button_state) { LED_Control(button_state); } } ``` 此代码片段展示了如何通过滴答计数器 `uwTick` 来精确控制按键的时间间隔,从而避免频繁误触。 #### 四、综合应用中的按键控制系统 在实际项目中,按键可能与其他传感器协同工作,例如温度测量、超声波距离检测等功能模块。这种情况下,建议采用分层结构设计,将不同功能封装成独立的任务单元[^2]。 例如,当按键用于切换显示模式时,可以在主循环中加入如下逻辑判断: ```c if (key_scan()) { mode++; // 更改模式变量 if (mode > 2) { // 循环回初始模式 mode = 0; } update_display(mode); // 更新显示屏内容 } ``` 这段代码假设存在三种不同的显示模式,每次按键都会依次切换至下一个模式。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值