CC2541_Key部分理解

此博文最后修改时间  2016-12-31


一、简介

CC2541按键程序部分理解

 

二、实验环境

协议栈版本:BLE-CC254x-1.3.2

编译软件:IAR 8.10

硬件:Smart RF开发板 CC2541

工程:SimpleBLEPeripheral

 

三、版权声明

博主:Jackie_Wuxi

声明:喝水不忘挖井人

 

四、细解(若理解有误,欢迎更正)

4.1前提

1阅读 AmoBLE-入门与提高教程(2014.10.22).pdf  P128

2CC2541之按键 http://blog.youkuaiyun.com/feilusia/article/details/47336473

4.2详解

 

main初始化

1-InitBoard(OB_READY ); 

 

2-InitBoard调用HalKeyConfig(OnboardKeyIntEnable, OnBoard_KeyCallback); 该函数开启了按键中断    //决定了按键是用中断查询的

 

Hal_KeyIntEnable 用于中断和轮询的判断,pHalKeyProcessFunction 即OnBoard_KeyCallback函数


HalKeyConfig配置P01falling edge 触发中断,也可以配置成rising edge


3-hal_key.c中HAL_ISR_FUNCTION(halKeyPort0Isr, P0INT_VECTOR )调用halProcessKeyInterrupt()  //P01 对应按键S1


4-halProcessKeyInterrupt初次判断按键是否按下,函数末尾启动定时HAL_KEY_EVENT,



 5-任务Hal_ProcessEvent判断HAL_KEY_EVENT事件并调用HalKeyPoll 判断出哪个按键按下

(步骤4启动HAL_KEY_EVENT事件到HalKeyPoll 函数判断出哪个按键,这段时间相当于延迟时间,用于按键去抖)

 

6-HalKeyPoll调用pHalKeyProcessFunction,相当于调用OnBoard_KeyCallback


 

7-OnBoard_KeyCallback调用OnBoard_SendKeys, 同时涉及按键发现方式切换

 

中断方式发现按键和扫描方式发现按键切换代码


HalKeyConfig函数中


8-OnBoard_SendKeys调用osal_msg_send(registeredKeysTaskID, (uint8 *)msgPtr );

 

9-接下来就跳到注册了key的任务事件SYS_EVENT_MSG中去

RegisterForKeys( SimpleBLETest_TaskID );


 

 10-最后在simpleBLEPeripheral_HandleKeys 处理


五、参考文献

http://blog.youkuaiyun.com/feilusia/article/details/47336473

<think>好的,用户现在问“KEY_DOWN是啥”,我需要解释清楚这个概念。首先,用户之前已经了解了状态机如何识别单击和双击,现在他们可能对其中提到的KEY_DOWN这个术语有疑问。KEY_DOWN通常指按键被按下的动作,但具体在编程或硬件中可能有不同的实现方式。 用户可能是在学习嵌入式系统或软件开发,特别是涉及用户输入处理的部分。他们可能不太清楚在代码中如何检测按键按下,或者KEY_DOWN具体代表什么。需要解释KEY_DOWN在不同上下文中的含义,比如在状态机中的事件触发,或者在硬件层面的电平变化。 接下来,我需要考虑用户的背景。他们可能具备一定的编程基础,但对硬件交互或状态机的具体实现不太熟悉。可能需要用简单的例子说明,比如在微控制器中,当按键被按下时,对应的GPIO引脚电平变化,驱动层检测到这个变化并生成KEY_DOWN事件。 还要区分不同场景下的KEY_DOWN,比如在操作系统中可能是一个键盘事件,而在嵌入式系统中是物理按键的状态变化。同时,用户可能想知道如何处理消抖(debounce)以及为什么在状态机中需要用到KEY_DOWN事件,比如在PRESS_DOWN状态时检测到KEY_DOWN会启动定时器。 需要确保解释清晰,避免使用过多专业术语,但又要准确。可能需要提到硬件和软件层面的不同处理方式,比如轮询和中断,以及为什么在状态机设计中采用事件驱动的方式。同时,可以举例说明代码中的KEY_DOWN是如何被检测的,比如通过读取寄存器值或使用中断服务例程。 最后,确认用户的问题是否已经解决,是否需要进一步的澄清或扩展。例如,用户可能后续会问如何处理KEY_UP或者消抖的具体实现,但目前只需专注于KEY_DOWN的定义和作用。确保回答结构清晰,分点说明,帮助用户逐步理解。</think>KEY_DOWN 是嵌入式/软件开发中描述**按键物理按下动作**的核心概念,其本质是硬件到软件的触发信号。以下从 3 个维度详细解析: 一、硬件层实现原理 1. 电平检测机制 - 机械按键闭合时产生电平变化(通常从高电平 $V_{CC}$ 跳变为低电平 $GND$) - 典型电路连接:$$ V_{CC} \rightarrow 电阻 \rightarrow 按键 \rightarrow GPIO引脚 $$ - 有效信号判断公式:$$ V_{in} \leq V_{IL(max)} \quad (例如: 3.3V系统需 \leq 0.8V) $$ 2. 信号捕获方式 ```c // 直接读取寄存器示例(ARM Cortex-M) #define KEY_PORT GPIOC #define KEY_PIN 13 _Bool is_key_down() { return !(KEY_PORT->IDR & (1 << KEY_PIN)); // 取反因上拉电阻设计 } ``` 二、软件层处理流程 1. 事件检测方法对比 | 方法 | 响应速度 | CPU占用 | 实现复杂度 | |-------------|---------|--------|-----------| | 轮询检测 | 慢(ms级) | 高 | 低 | | 外部中断 | 快(μs级) | 低 | 中 | | 定时器扫描 | 中(10μs级)| 中 | 高 | 2. 典型消抖处理代码 ```c // 状态机消抖算法 #define DEBOUNCE_TICKS 5 // 20ms@4kHz扫描 static uint8_t filter_counter = 0; _Bool get_stable_key() { _Bool raw_state = is_key_down(); if(raw_state != last_state) { filter_counter = 0; } else { if(filter_counter < DEBOUNCE_TICKS) { filter_counter++; } } last_state = raw_state; return (filter_counter >= DEBOUNCE_TICKS) ? raw_state : last_stable_state; } ``` 三、系统级交互特性 1. 事件传递时序 ``` 物理接触 → 硬件电平变化 → 驱动层捕获 → 消抖滤波 → 应用层事件(KEY_DOWN) ↓ [经过 t_hold 时间后可能触发长按事件] ``` 2. 多任务环境处理要点 - 使用消息队列传递按键事件 - 中断服务程序(ISR)中仅做标记 - 在主循环中处理状态机 - 临界区保护(例如关闭中断修改共享标志) 实践案例:在STM32的HAL库中,可通过回调函数处理: ```c void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == KEY_PIN) { if(HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET) { key_event_queue_push(KEY_DOWN); // 压入事件队列 } } } ``` 特殊场景应对: 1. 矩阵键盘:通过行列扫描检测 KEY_DOWN 2. 电容触摸:通过电荷变化率判断按压 3. 防水按键:需要增加脉冲计数验证 4. 工业环境:需设置 Schmitt Trigger 输入滤波 注:现代HMI设计常将 KEY_DOWN 细分为多个阶段: - Pre-press(接触初期检测) - Soft press(未达触发阈值的轻按) - Full press(有效按键) - Over press(超行程保护)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值