关于4051开发板的按键学习

来源:互联网 发布:数据挖掘戴红课后答案 编辑:程序博客网 时间:2024/05/23 11:52

一、简介

本篇介绍如何在SimpleBLECentral工程和SimpleBLEPeripheral工程中使用按键,并且剖析按键的初始化、响应的流程。


二、实验平台

协议栈版本:BLE-CC254x-1.4.0

编译软件:IAR 8.20.2

硬件平台:Smart RF开发板


三、版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.net/feilusia

联系方式:897503845@qq.com

技术交流QQ群:127442605


四、硬件原理图

1、普通按键


触发引脚:P0_1

常态:低电平

按下:高电平

松开:低电平

适合触发方式:上升沿触发


2、五向按键

原理:五向按键每一端连接或与芯片SN74HC32D,使得按下五向按键即可触发P2_0。随即从P0_6采集双级运算放大芯片TLV272输出的电压,来确定是五向按键的哪个脚。

1)触发

触发引脚:P2_0

触发引脚常态:低电平

触发引脚按下:高电平

触发引脚松开:低电平

适合触发方式:上升沿触发

2)采集

采集引脚:P0_6

无按键时电压:2.39V

按center键时电压:2.39V

按up键时电压:0.41V

按down键时电压:1.36V

按left键时电压:1.85V

按right键时电压:2.05V


五、SimpleBLEPeripheral工程的按键代码修改

注:SimpleBLECentral工程步骤也类似,只是少了几步去除代码中的宏定义“CC2540_MINIDK”的步骤。

1、IAR的宏定义

要想使用按键,首先在IAR的设置中的宏定义里添加“HAL_KEY = TRUE”;反之,则“HAL_KEY = FALSE”。

注:由于协议栈中有下面这段代码,因此即使IAR的宏定义设置中没有添加“HAL_KEY = TRUE”也可以使用按键。

[cpp] view plain copy
  1. /* Set to TRUE enable KEY usage, FALSE disable it */  
  2. #ifndef HAL_KEY  
  3. #define HAL_KEY TRUE  
  4. #endif  
建议在IAR的宏定义中手动添加,以防出现不必要的错误。


2、修改应用层代码(SimpleBLEPeripheral.c中)

1)应用层的按键事件入口处



2)simpleBLEPeripheral_HandleKeys的声明



3)simpleBLEPeripheral_HandleKeys函数


把工程默认的按键处理也都删了,否则代码编译会报错。


4)注册按键事件


2、按键驱动代码修改(hal_key.c)

1)修改按键S1的边沿触发方式

[cpp] view plain copy
  1. #define HAL_KEY_SW_6_EDGE     HAL_KEY_RISING_EDGE//HAL_KEY_FALLING_EDGE  
由于我的板子适合上升沿触发,而协议栈默认是下降沿触发,因此这里配置成上升沿。


2)修改五向按键的边沿触发方式

[cpp] view plain copy
  1. #define HAL_KEY_JOY_MOVE_EDGE     HAL_KEY_RISING_EDGE//HAL_KEY_FALLING_EDGE  


3)更正协议栈的错误代码

[cpp] view plain copy
  1. //    /* Rising/Falling edge configuratinn */  
  2. //    HAL_KEY_JOY_MOVE_ICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT);    /* Clear the edge bit */  
  3. //    /* For falling edge, the bit must be set. */  
  4. //  #if (HAL_KEY_JOY_MOVE_EDGE == HAL_KEY_FALLING_EDGE)  
  5. //    HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;  
  6. //  #endif  
  7.       
  8.     /* Rising/Falling edge configuratinn */  
  9.     PICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT);    /* Clear the edge bit */  
  10.     /* For falling edge, the bit must be set. */  
  11.   #if (HAL_KEY_JOY_MOVE_EDGE == HAL_KEY_FALLING_EDGE)  
  12.     PICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;  
  13.   #endif  

原代码错将中断使能寄存器HAL_KEY_JOY_MOVE_ICTL(P2IEN)当做PICTL寄存器。详情如下:

[cpp] view plain copy
  1. #define HAL_KEY_JOY_MOVE_ICTL     P2IEN /* Port Interrupt Control register */  




4)修改HalKeyPoll函数

[cpp] view plain copy
  1. //  if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT))    /* Key is active low */  
  2. //  {  
  3. //    keys |= HAL_KEY_SW_6;  
  4. //  }  
  5.   if ((HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT))    /* Key is active high */    
  6.   {  
  7.     keys |= HAL_KEY_SW_6;  
  8.   }  
1.4.0的协议栈才要这么做。


六、解析按键初始化

1、复位按键的相关参数、变量







2、注册任务ID



3、正式初始化按键配置



下图默认开启中断,并且按键的回调函数注册为OnBoard_KeyCallback。



七、解析按键响应

1、扫描按键值

1)当硬件有按键时,则进入中断服务函数halProcessKeyInterrupt



2)HAL_KEY_EVENT事件

在Hal_ProcessEvent中的HAL_KEY_EVENT事件中扫描按键。



3)扫描按键值HalKeyPoll




2、将按键值送往上层的应用层

1)OnBoard_KeyCallback函数



2)OnBoard_SendKeys函数


通过osal_msg_send传递的消息,都会到选中的任务下的默认事件下(此时也就是simpleBLEPeripheral_TaskID任务的SYS_EVENT_MSG事件)。


3)应用层处理





八、解析按键中一处难点

1、难懂的代码

[cpp] view plain copy
  1. /* If any key is currently pressed down and interrupt 
  2.    is still enabled, disable interrupt and switch to polling */  
  3. if( keys != 0 )  
  4. {  
  5.   if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )  
  6.   {  
  7.     OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;  
  8.     HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);  
  9.   }  
  10. }  
  11. /* If no key is currently pressed down and interrupt 
  12.    is disabled, enable interrupt and turn off polling */  
  13. else  
  14. {  
  15.   if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )  
  16.   {  
  17.     OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;  
  18.     HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);  
  19.   }  
  20. }  

OnBoard_KeyCallback函数中还有上面的一段代码很难理解,百度后无果,自己也是单步执行跑完按键流程后才理解这段代码的用途。

这段代码是实现中断方式和扫描方式互相切换。

作用是检测键值是否松开:

1)当“硬件上的按键不按为高电平,按下为低电平”时:下降沿触发时我们可以知道何时按键松开。

2)当“硬件上的按键不按为低电平,按下为高电平”时:上升沿触发时我们可以知道何时按键松开。


注:下面这个框中代码就是用于中断方式与查询方式来回切换用的。

它是指查询到键值回零后、由查询方式转为中断方式时,停止定时器。


2、详细分析

下面以“硬件上的按键不按为低电平,按下为高电平”、“上升沿触发”为前提,看下面的按键流程:

功能:中断方式检测按键按下、扫描方式检测按键松开。(按键松开会通知用户)

1)按键S1按下:

触发上升沿中断,发送键值“0x20”给应用层。

由中断触发方式切换成扫描方式。


2)按键S1松开

扫描到引脚变化,则发送键值“0x00”给应用层。

由扫描方式切换回中断触发方式。


3、小实验

接下来测试下按键流程是否跟我解析的一致,这里只测试上升沿触发的情况。

1、代码修改:

[cpp] view plain copy
  1. static void simpleBLEPeripheral_HandleKeys( uint8 shift, uint8 keys )  
  2. {  
  3.   VOID shift;  // Intentionally unreferenced parameter   
  4.   
  5.   if ( keys & HAL_KEY_SW_6 )//上升沿触发,按键按下  
  6.   {    
  7.     NPI_PrintString("key is press!\r\n");    
  8.   }  
  9.     
  10.   if ( keys == 0x00 )    //上升沿触发,按键松开  
  11.   {  
  12.     NPI_PrintString("key is loosen!\r\n");    
  13.   }    
  14. }  

2、实验现象:


按键按下时是中断方式发现按键,并发送0x20键值给应用层,此时显示“key is press!”。

按键松开时是扫描方式扫到按键,并发送0x00键值给应用层,此时显示“key is loosen!”。

实验结果与我分析的一致。

0 0
原创粉丝点击