cc2540中文数据手册哪个脚可能作为按键使用

协议栈按键事件
修改工程配置使能按键功能
添加头文件
协议栈中定义宏开关
//自定义宏开关
#if&defined(&CC2540_MINIDK&)||(MT254xboard)
//函数声明按键响应
static&void&simpleBLEPeripheral_HandleKeys(&uint8&shift,&uint8&keys&);
//init函数中定义&&
#if&defined&(MT254xboard)
&&&&//&Register&for&all&key&events&-&This&app&will&handle&all&key&events
&&RegisterForKeys(&simpleBLEPeripheral_TaskID&);
static&void&simpleBLEPeripheral_ProcessOSALMsg(&osal_event_hdr_t&*pMsg&)
&&switch&(&pMsg-&event&)
&&#if&defined(&CC2540_MINIDK&)||(MT254xboard)
&&&&case&KEY_CHANGE:
&&&&&&simpleBLEPeripheral_HandleKeys(&((keyChange_t&*)pMsg)-&state,&((keyChange_t&*)pMsg)-&keys&);
&&#endif&//&#if&defined(&CC2540_MINIDK&)
&&default:
&&&&//&do&nothing
#if&defined(&CC2540_MINIDK&)||(MT254xboard)
/*********************************************************************
&*&@fn&&&&&&simpleBLEPeripheral_HandleKeys
&*&@brief&&&Handles&all&key&events&for&this&device.
&*&&&&&&&&&&按键响应操作
&*&@param&&&shift&-&true&if&in&shift/alt.
&*&@param&&&keys&-&bit&field&for&key&events.&Valid&entries:
&*&&&&&&&&&&&&&&&&&HAL_KEY_SW_2
&*&&&&&&&&&&&&&&&&&HAL_KEY_SW_1
&*&@return&&none
static&void&simpleBLEPeripheral_HandleKeys(&uint8&shift,&uint8&keys&)
&&//uint8&SK_Keys&=&0;
&&VOID&&&//&Intentionally&unreferenced&parameter
&&if&(&keys&&&HAL_KEY_UP&)
&&&&&&SerialPrintf(&%s\r\n&,&&Key&Up&);
&&&&if&(&keys&&&HAL_KEY_RIGHT&)
&&&&&&SerialPrintf(&%s\r\n&,&&Key&right&);
&&&&if&(&keys&&&HAL_KEY_CENTER&)
&&&&&&SerialPrintf(&%s\r\n&,&&Key&center&);
&&&&if&(&keys&&&HAL_KEY_LEFT&)
&&&&&&SerialPrintf(&%s\r\n&,&&Key&left&);
&&&&if&(&keys&&&HAL_KEY_DOWN&)
&&&&&&SerialPrintf(&%s\r\n&,&&Key&down&);
&&&&if&(&keys&&&HAL_KEY_SW_6&)
&&&&&&SerialPrintf(&%s\r\n&,&&Button&down&);
#endif&//&#if&defined(&CC2540_MINIDK&)
修改五向按键值的电压范围&在文件中
#if&!defined&(&CC2540_MINIDK&)
/**************************************************************************************************
&*&@fn&&&&&&halGetJoyKeyInput
&*&@brief&&&Map&the&ADC&value&to&its&corresponding&key.
&*&&&&&&&&&&按键值对应的电压范围
&*&@param&&&None
&*&@return&&keys&-&current&joy&key&status
&**************************************************************************************************/
uint8&halGetJoyKeyInput(void)
&&/*&The&joystick&control&is&encoded&as&an&analog&voltage.
&&&*&Read&the&JOY_LEVEL&analog&value&and&map&it&to&joy&movement.
&&uint8&ksave0&=&0;
&&uint8&ksave1;
&&/*&Keep&on&reading&the&ADC&until&two&consecutive&key&decisions&are&the&same.&*/
&&&&ksave1&=&ksave0;&&&&/*&save&previouse&key&reading&*/
&&&&adc&=&HalAdcRead&(HAL_KEY_JOY_CHN,&HAL_ADC_RESOLUTION_10);
&&&&&if&((adc&&=&2)&&&&(adc&&=&160))&&&&&&&&&&&&//&right&&&&172
&&&&&&&&ksave0&|=&HAL_KEY_RIGHT;
&&&&else&if&((adc&&=&161)&&&&(adc&&=&180))&&&&&//&cen&146
&&&&&&ksave0&|=&HAL_KEY_CENTER;
&&&&else&if&((adc&&=&181)&&&&(adc&&=&220))&&&&//&up&&&&&204
&&&&&&&ksave0&|=&HAL_KEY_UP;&&&&&&&
&&&&else&if&((adc&&=&221)&&&&(adc&&=&270))&&&&//&left&&&256
&&&&&&ksave0&|=&HAL_KEY_LEFT;&&&&&
&&&&else&if&((adc&&=&271)&&&&(adc&&=&350))&&&&//&down&&&&306
&&&&&ksave0&|=&HAL_KEY_DOWN;
&&}&while&(ksave0&!=&ksave1);
&&return&ksave0;
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:191484次
积分:5329
积分:5329
排名:第2382名
原创:359篇
转载:20篇
(1)(3)(3)(12)(7)(15)(3)(6)(10)(7)(5)(2)(4)(3)(12)(5)(5)(15)(13)(12)(15)(37)(186)用心创造滤镜
扫码下载App
汇聚2000万达人的兴趣社区下载即送20张免费照片冲印
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
我是个懒人
我喜欢黑头发,有立体感的,比我聪明的,金牛、天蝎、天秤的
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
在介绍蓝牙按键流程分析之前,我们需要了解一个概念,那就是就是OSAL。什么是OSAL呢?可能大伙对于OS是比较了解的,学了计算机的搞过OS的也基本接触过,简单来说就是一个操作系统抽象层,可以理解为运行在 CC2540 上的操作系统,说操作系统还不能算,TI的OSAL只实现了任务切换和消息机制。并且把协议栈的代码、硬件处理的代码,用户程序的代码等分别放到了 OSAL 层的不同任务处理函数中去了,各任务函数之间通过消息机制、同一个任务之间通过事件的的方式来通信。什么是 EVENT 事件?OSAL 为每个任务函数分配了一个 16 位的事件变量,每一位代表一个事件,最高位为 0x8000表示为系统事件 SYS_EVENT_MSG。其余的15 位留给用户自定义需要的事件。通常事件由定时器启动,比如一秒后我要点亮 LED2,这就需要发送一个点亮 LED2 的事件,然后等待定时器1s后溢出,于是启动点亮 LED2事件,事件会调用相应的hal 层API点亮LED2。什么是 MSG 消息MSG 是比 EVENT 事件更具体并且可以携带数据的一种通信方式,MSG 的标记是按数值,而不是按位。比如 0x01 和 0x02 是两个不同的消息,但对于事件 0x03 则是 0x01 事件和 0x02 事件的组合。MSG 收发使用 osal_msg_send()和 osal_msg_receive();当调用 osal_msg_send()发送一个 msg 的同时会在 EVENT 列表中触发一个 message ready event。(请注意最后一句话,这句话点出了为什么按键时间的触发为何会导致系统事件也接受到了)现在以 SimpleBLEPeripheral 为例说明按键流程在 SimpleBLEPeripheral 任务初始化函数中有这样一条代码:& // Register for all key events - This app will handle all key events& RegisterForKeys( simpleBLEPeripheral_TaskID );这个函数来自 OnBoard.c 源文件中/********************************************************************** Keyboard Register function** The keyboard handler is setup to send all keyboard changes to* one task (if a task is registered).** If a task registers, it will get all the keys. You can change this* to register for individual keys.*********************************************************************/uint8 RegisterForKeys( uint8 task_id ){& // Allow only the first task& if ( registeredKeysTaskID == NO_TASK_ID )& {& & registeredKeysTaskID = task_& & return ( true );& }& else& & return ( false );}向一个全局变量 registeredKeysTaskID中赋值自己的任务 ID,调用了这个函数就能成功注册按键服务,那这个全局变量在何时使用呢?分析到这里,感觉有点迷糊了,我们可以从顶到下分析。任何一个程序都是从main函数开始的,这点我们要坚信。所以我们首先找到这个main函数打开SimpleBLEPeripheral_Main.c文件可以看到/*************************************************************************************************** @fn & & & & &main** @brief & & & Start of application.** @param & & & none** @return & & &none***************************************************************************************************/int main(void){& /* Initialize hardware */& HAL_BOARD_INIT(); &&& // Initialize board I/O& InitBoard( OB_COLD );& /* Initialze the HAL driver */& HalDriverInit();& /* Initialize NV system */& osal_snv_init();& /* Initialize LL */& /* Initialize the operating system */& osal_init_system();& /* Enable interrupts */& HAL_ENABLE_INTERRUPTS();& // Final board initialization& InitBoard( OB_READY );& #if defined ( POWER_SAVING )& & osal_pwrmgr_device( PWRMGR_BATTERY );& #endif& /* Start OSAL */& osal_start_system(); // No Return from here& return 0;}我们打开 InitBoard( OB_READY );可以看到如下代码/********************************************************************** @fn & & &InitBoard()* @brief & Initialize the CC2540DB Board Peripherals* @param & level: COLD,WARM,READY* @return &None*/void InitBoard( uint8 level ){& if ( level == OB_COLD )& {& & // Interrupts off& & osal_int_disable( INTS_ALL );& & // Turn all LEDs off& & HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF );& & // Check for Brown-Out reset// & &ChkReset();& }& else &// !OB_COLD& {& & /* Initialize Key stuff */& & OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;& & //OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;& & HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);& }}看到我上面标注的函数了吧?那个是一个按键回调服务注册函数,注册了一个OnBoard_KeyCallback函数HalKeyConfig 函数的实现:将上述的回调函数的地址复制给了函数指针变量。通过跟踪发现该函数的指针变量在按键的轮询函数中调用了,如下图:/*************************************************************************************************** @fn & & &HalKeyPoll** @brief & Called by hal_driver to poll the keys** @param & None** @return &None**************************************************************************************************/void HalKeyPoll (void){& uint8 keys = 0;& uint8 notify = 0;#if defined (CC2540_MINIDK)& if (!(HAL_KEY_SW_1_PORT & HAL_KEY_SW_1_BIT)) & &/* Key is active low */& {& & keys |= HAL_KEY_SW_1;& }& if (!(HAL_KEY_SW_2_PORT & HAL_KEY_SW_2_BIT)) & &/* Key is active low */& {& & keys |= HAL_KEY_SW_2;& }#else& if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT)) & &/* Key is active low */& {& & keys |= HAL_KEY_SW_6;& }& if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT)) &/* Key is active HIGH */& {& & keys = halGetJoyKeyInput();& }#endif& /* If interrupts are not enabled, previous key status and current key status& &* are compared to find out if a key has changed status.& &*/& if (!Hal_KeyIntEnable)& {& & if (keys == halKeySavedKeys)& & {& & & /* Exit - since no keys have changed */& & && & }& & else& & {& & & notify = 1;& & }& }& else& {& & /* Key interrupt handled here */& & if (keys)& & {& & & notify = 1;& & }& }& /* Store the current keys for comparation next time */& halKeySavedKeys =& /* Invoke Callback if new keys were depressed */& if (notify && (pHalKeyProcessFunction))& {& & (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);& }}在这里底层的按键查询函数调用一个函数指针,而非具体的函数,这样就将处理按键的接口留给了上层,上层应用中,叧需解析的函数指针传入的参数 1:keys 就知道是哪个按键被按下了。我们再回到刚才的 OnBoard_KeyCallback 回调函数处,该回调函数代码如下:/********************************************************************** @fn & & &OnBoard_KeyCallback** @brief & Callback service for keys** @param & keys &- keys that were pressed* & & & & &state - shifted** @return &void*********************************************************************/void OnBoard_KeyCallback ( uint8 keys, uint8 state ){& uint8& (void)& // shift key (S1) is used to generate key interrupt& // applications should not use S1 when key interrupt is enabled& shift = (OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE) ? false : ((keys & HAL_KEY_SW_6) ? true : false);& if ( OnBoard_SendKeys( keys, shift ) != SUCCESS ) &//就是这句话将按键消息上传到应用层去处理的& {& & // Process SW1 here& & if ( keys & HAL_KEY_SW_1 ) &// Switch 1& & {& & }& & // Process SW2 here& & if ( keys & HAL_KEY_SW_2 ) &// Switch 2& & {& & }& & // Process SW3 here& & if ( keys & HAL_KEY_SW_3 ) &// Switch 3& & {& & }& & // Process SW4 here& & if ( keys & HAL_KEY_SW_4 ) &// Switch 4& & {& & }& & // Process SW5 here& & if ( keys & HAL_KEY_SW_5 ) &// Switch 5& & {& & }& & // Process SW6 here& & if ( keys & HAL_KEY_SW_6 ) &// Switch 6& & {& & }& }& /* If any key is currently pressed down and interrupt& & &is still enabled, disable interrupt and switch to polling */& if( keys != 0 )& {& & if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )& & {& & & OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;& & & HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);& & }& }& /* If no key is currently pressed down and interrupt& & &is disabled, enable interrupt and turn off polling */& else& {& & if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )& & {& & & OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;& & & HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);& & }& }}进入按键消息发送函数中可以看到/********************************************************************** @fn & & &OnBoard_SendKeys** @brief & Send "Key Pressed" message to application.** @param & keys &- keys that were pressed* & & & & &state - shifted** @return &status*********************************************************************/uint8 OnBoard_SendKeys( uint8 keys, uint8 state ){& keyChange_t *msgP& if ( registeredKeysTaskID != NO_TASK_ID )& {& & // Send the address to the task& & msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );& & if ( msgPtr )& & {& & & msgPtr-&hdr.event = KEY_CHANGE;& & & msgPtr-&state =& & & msgPtr-&keys =& & & osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );& & }& & return ( SUCCESS );& }& else& & return ( FAILURE );}主要是将按键时间,状态和按键值打包到信息中最后通过 osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );发送到注册了按键服务的应用层去 ,最终用户按了哪个按键,如何响应该按键在系统事件 SYS_EVENT_MSG 中处理。疑问又来了,为什么通过 osal_msg_send 收发的消息会出现在 SYS_EVENT_MSG 中呢?这个疑问,就是刚才我说过的osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr )会产生一个 a message &ready event in the destination tasks event list./********************************************************************** @fn & & &osal_msg_send** @brief** & &This function is called by a task to send a command message to* & &another task or processing element. &The sending_task field must* & &refer to a valid task, since the task ID will be used* & &for the response message. &This function will also set a message* & &ready event in the destination tasks event list.*** @param & uint8 destination_task - Send msg to Task ID* @param & uint8 *msg_ptr - pointer to new message buffer** @return &SUCCESS, INVALID_TASK, INVALID_MSG_POINTER*/uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr ){& return ( osal_msg_enqueue_push( destination_task, msg_ptr, FALSE ) );}/********************************************************************** @fn & & &simpleBLEPeripheral_ProcessOSALMsg** @brief & Process an incoming task message.** @param & pMsg - message to process** @return &none*/static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg ){& switch ( pMsg-&event )& {& #if defined( CC2540_MINIDK )& & case KEY_CHANGE: & & & & & & & & &//按键处理事件,用户产生的按键都是在这里处理 & && & & simpleBLEPeripheral_HandleKeys( ((keyChange_t *)pMsg)-&state, ((keyChange_t *)pMsg)-&keys );& & && #endif // #if defined( CC2540_MINIDK )& default:& & // do nothing& && }}在 SimpleBLEPeripheral 中,对按键的响应如下:joystick right(SW2)收发广播的开启和关闭/********************************************************************** @fn & & &simpleBLEPeripheral_HandleKeys** @brief & Handles all key events for this device.** @param & shift - true if in shift/alt.* @param & keys - bit field for key events. Valid entries:* & & & & & & & & HAL_KEY_SW_2* & & & & & & & & HAL_KEY_SW_1** @return &none*/static void simpleBLEPeripheral_HandleKeys( uint8 shift, uint8 keys ){& uint8 SK_Keys = 0;& VOID &// Intentionally unreferenced parameter& if ( keys & HAL_KEY_SW_1 )& {& & SK_Keys |= SK_KEY_LEFT;& }& if ( keys & HAL_KEY_SW_2 )& {& & SK_Keys |= SK_KEY_RIGHT;& & // if device is not in a connection, pressing the right key should toggle& & // advertising on and off& & if( gapProfileState != GAPROLE_CONNECTED )& & {& & & uint8 current_adv_enabled_& & & uint8 new_adv_enabled_& & & //Find the current GAP advertisement status& & & GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &current_adv_enabled_status ); //这个函数主要就是获得广播的开启和关闭状态& & & if( current_adv_enabled_status == FALSE )& & & {& & & & new_adv_enabled_status = TRUE;& & & }& & & else& & & {& & & & new_adv_enabled_status = FALSE;& & & }& & & //change the GAP advertisement status to opposite of current status& & & GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status );& & }& }& // Set the value of the keys state to the Simple Keys P& // This will send out a notification of the keys state if enabled& SK_SetParameter( SK_KEY_ATTR, sizeof ( uint8 ), &SK_Keys );}#endif // #if defined( CC2540_MINIDK )现在按键基本分析完了,其实CC2540学习板子是默认开启广播,但是Keyfob就需要按键手动开启了。接下来我会继续分析协议栈的其他功能,如有不足之外,望补充~~~~~~~~~~(花了我几个小时写出来,蛋疼。写文章太费劲了)转自:.cn/forum.php?mod=viewthread&tid=428987
阅读(139)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'【转】TI CC2540 HAL_KEY.C 分析',
blogAbstract:'之前在蓝牙技术群看到好多网友不知道按键流程到底是什么情况,平时也没时间,在群里也一两句说不明白,也就说了下可以去看下zigbee按键流程过程,其实都是相通的,现在特意发帖分享下,希望能起到一个抛砖引玉的作用。在介绍蓝牙按键流程分析之前,我们需要了解一个概念,那就是就是OSAL。什么是OSAL呢?可能大伙对于OS是比较了解的,学了计算机的搞过OS的也基本接触过,简单来说就是一个操作系统抽象层,可以理解为运行在 CC2540 上的操作系统,说操作系统还不能算,TI的OSAL只实现了任务切换和消息机制。并且把协议栈的代码、硬件处理的代码,用户程序的代码等分别放到了 OSAL 层的不同任务处理函数中去了,各任务函数之间通过消息机制、同一个任务之间通过事件的的方式来通信。什么是 EVENT 事件?',
blogTag:'ble',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:1,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'我是个懒人\r\n我喜欢黑头发,有立体感的,比我聪明的,金牛、天蝎、天秤的',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}CC2540 BLE Trainning 中文_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
CC2540 BLE Trainning 中文
C​C50​ ​B​L​E​ ​T​r​a​i​n​n​i​n​g​ ​中​文
阅读已结束,如果下载本文需要使用
想免费下载本文?
你可能喜欢- amoBBS 阿莫电子论坛
后使用快捷导航没有帐号?
随时随地,快速访问
只要手机在手,您都可以快速、方便地看贴发帖,与论坛好友收发短消息。
极致优化,畅快"悦"读
独有的论坛界面和触屏设计,手机论坛也变得赏心悦目,操作自如。
即拍即发,分享生活
不管是风景图画,还是新闻现场,拍照发帖一气呵成,让您在论坛出尽风头。
下载客户端后,拍摄二维码快速访问本站:
或者通过以下地址访问:
阿莫电子论坛, 原"中国电子开发网"

我要回帖

更多关于 ti cc2540 usb 驱动 的文章

 

随机推荐