首页 > 代码库 > TI CC2541的狗日的Key

TI CC2541的狗日的Key

被突如其来的一个bug困扰了, 起因是, 按键接的红外接收器, 结果发现, 一旦按下之后, IEN1, P0IE的标识位bit5, 被不知道特么的谁归0了, 也就是说, 按键只能被按下一次, 再按就不进中断了.

技术分享

 

后来研究了甜总的自定义按键.

http://blog.csdn.net/feilusia/article/details/50535963

发现按键根本不进中断.

接着, 又参考另一个文章:

http://www.cnblogs.com/chenzhao207/articles/4483189.html

不用协议栈, 直接做成一个文件, debug成功.

然后我才想起, 带协议编译的时候IAR有一句警告, 我没有注意, 就是说我后来定义的key中断跟hal_key文件里面定义的中断处理重复了.

于是, 我把编译的参数HAL_KEY=FALSE, 还把board_init时候的key_config给干掉, 终于成功的在协议栈里面进了中断.

 

今天早上看了代码我才明白, 原来key的响应在OnBoard.c文件里面, 直接就是这个:

HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

而在hal_key.c里面:

HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
{
  HAL_ENTER_ISR();

  if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT)

  {
    halProcessKeyInterrupt();
  }

  /*
    Clear the CPU interrupt flag for Port_0
    PxIFG has to be cleared before PxIF
  */

  HAL_KEY_SW_6_PXIFG = 0;

  HAL_KEY_CPU_PORT_0_IF = 0;

  CLEAR_SLEEP_MODE();

  HAL_EXIT_ISR();
  return;
}

 

上面这一段就是中断声明, 怎么知道的呢, 天杀的IAR没法进行全局的搜索, 还是用SI找到的:

(原来IAR的全局搜索要Ctrl+Alt+F的).

 

Hal_mcu.h 里面

#define HAL_ISR_FUNC_PROTOTYPE(f,v)     _PRAGMA(vector=v) __near_func __interrupt void f(void)
#define HAL_ISR_FUNCTION(f,v)           HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v)

原来HAL_ISR_FUNCTION(f,v) 就是 HAL_ISR_FUNC_PROTOTYPE(f,v);跟HAL_ISR_FUNC_DECLARATION(f,v)

而 HAL_ISR_FUNC_PROTOTYPE(f,v) 又是 _PRAGMA(vector=v) __near_func __interrupt void f(void)

所以 HAL_ISR_FUNCTION 就是中断处理的函数啊...

会跟

#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void){

}

起冲突的.

接下来要做的步骤:

 

1. 把系统的Key都干掉, 研究一下OnBoard.c里面的HalKeyConfig都有啥.

2. 如果没啥了, 就使用自己写的key的中断.

3. 检查中断响应的函数, EA=0肯定是不对的, 停掉P0IEN对应的bit位比较合理.

4. 测试红外的效果.

 

TI CC2541的狗日的Key