This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

按键中断没起作用

Other Parts Discussed in Thread: CC2541, CC2540

ti工程师,你好

   有个问题,就是用cc2541,1个动作一直执行下去,知道按下键产生一个中断,才跳出来。

while(1)

{

...............动作

if(按键中断)

break;

}

if(按键中断)要怎么处理。

祝好

谢谢

lincoln

  • 是用p0_1这个端口,用keyfob这个工程代码。谢谢

  • 你好,ti工程师

        我想知道keyfob工程,按键只调用了查询HalKeyPoll (void),还是查询与中断同时用了,

       我发现HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ) ,这个按键中断好像没起作用。我那个循环跳不出来。

    谢谢

    lincoln

  • yuhua lincoln,

    中断和轮询是配合一起使用的。先中断,然后再用轮询来去抖。

    你P0_1的中断怎么配置的?

    另外你那while(1) 把系统挂起了,其他什么都干不了了,你这种最好用timer去定时判断。

    if(按键中断)我觉得你可以用一个标志位,进中断的时候设置一下,然后在这里判断一下,再清除这个标志位。

  • 你好,yan

    while(1)

    {

    .....动作

    if(flag==1)

    {

    flag=0;

    break;

    }

    }

    HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
    {
      HAL_ENTER_ISR();

    #if defined ( CC2540_MINIDK )
      if ((HAL_KEY_SW_1_PXIFG & HAL_KEY_SW_1_BIT) || (HAL_KEY_SW_2_PXIFG & HAL_KEY_SW_2_BIT))
    #else
      if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT)
    #endif
      {
        halProcessKeyInterrupt();
      }

      /*
        Clear the CPU interrupt flag for Port_0
        PxIFG has to be cleared before PxIF
      */
    #if defined ( CC2540_MINIDK )
      HAL_KEY_SW_1_PXIFG = 0;
      HAL_KEY_SW_2_PXIFG = 0;
    #else
      HAL_KEY_SW_6_PXIFG = 0;
    #endif
      HAL_KEY_CPU_PORT_0_IF = 0;
     
        {

    uint 8 flag;
    flag=1;
        }
      CLEAR_SLEEP_MODE();

      HAL_EXIT_ISR();

      return;
    }

    还是没起作用。

    怎么才能起作用。

    还有用定时器怎么处理这个动作。

    谢谢

    祝好

    lincoln

  • yuhua lincoln ,

    1. 不要用while(1)去做,加timer进行轮询,

    2. 你中断能进去吗?P0_1是怎么配置的?input, 中断使能了吗?

  • 官方的中断编程很繁琐,

    你可以写个简单的中断程序。

  • yan,你好


    1. 不要用while(1)去做,加timer进行轮询,

    》》》》》》加timer进行轮询,是轮询按键还是我这个动作。我这个动作只是按键时才能停止,其它时候一直操作。简单帮我讲下流程。

    2. 你中断能进去吗?P0_1是怎么配置的?input, 中断使能了吗?

    》》》》》》没进去,我看程序里p0_1好像都设置了,就没动它。只是置标志,根据你讲的标志判断。


    void HalKeyInit( void )
    {
      halKeySavedKeys = 0;  // Initialize previous key to 0.

    #if defined ( CC2540_MINIDK )
      HAL_KEY_SW_1_SEL &= ~(HAL_KEY_SW_1_BIT);    /* Set pin function to GPIO */
      HAL_KEY_SW_1_DIR &= ~(HAL_KEY_SW_1_BIT);    /* Set pin direction to Input */
      HAL_KEY_SW_2_SEL &= ~(HAL_KEY_SW_2_BIT);    /* Set pin function to GPIO *//////p0_1设置吧
      HAL_KEY_SW_2_DIR &= ~(HAL_KEY_SW_2_BIT);    /* Set pin direction to Input *///////p0_1设置吧
    #else
      HAL_KEY_SW_6_SEL &= ~(HAL_KEY_SW_6_BIT);    /* Set pin function to GPIO */
      HAL_KEY_SW_6_DIR &= ~(HAL_KEY_SW_6_BIT);    /* Set pin direction to Input */
      HAL_KEY_JOY_MOVE_SEL &= ~(HAL_KEY_JOY_MOVE_BIT); /* Set pin function to GPIO */
      HAL_KEY_JOY_MOVE_DIR &= ~(HAL_KEY_JOY_MOVE_BIT); /* Set pin direction to Input */

      P2INP |= PUSH2_BV;  /* Configure GPIO tri-state. */
    #endif

      /* Initialize callback function */
      pHalKeyProcessFunction  = NULL;

      /* Start with key is not configured */
      HalKeyConfigured = FALSE;

    #if defined ( CC2540_MINIDK )
      /* Rising/Falling edge configuratinn */
      PICTL |= HAL_KEY_SW_1_EDGEBIT;   /* Set the edge bit to set falling edge to give int */ 中断下降沿触发
      HAL_KEY_SW_1_IEN |= ( HAL_KEY_SW_1_IENBIT | HAL_KEY_SW_2_IENBIT );   /* enable CPU interrupt */ 中断使能
    #endif
    }
      #define HAL_ENTER_ISR()               { halIntState_t _isrIntState = EA; HAL_ENABLE_INTERRUPTS();//这个是定义总中断开吧。


    是不是我还没真正搞清流程,自己简单写个按键中断,会影响以前的按键操作吗?

    谢谢

    lincoln

  • yuhua lincoln,

    1. 轮询你的按键状态,如果你是跟keyfob参考设计一样那种单纯按住就接地的按键,那只要轮询GPIO的输入状态就行。

    2. 你这个就很奇怪了,如果是和默认keyfob一样的GPIO设计的话,P0_1按下就应该能进中断的,你的代码看上去设置也应该没有问题,至少从中断配置上看。注意是下降沿触发,不知你的板子上按键设计是怎么样的。

    HAL_ENTER_ISR()是为了绕开IAR的一个bug而存在的。

    自己写中断也不会影响按键操作,只要配置IO,使能P0的中断,使能P0_1的中断,应该很简单的,然后中断处理函数就用原来的就行,看看能不能进中断。另外你还可以在debug的时候暂停一下,可以用IAR看每个GPIO端口的状态,中断标志位,各个IO目前的状况,很清晰。

  • 你好,yan

    我简单写了一个p0_1按键中断(我板子是按键接地,应该是下降沿触发)

    void HalKeyInit( void )

    {

    ................................

    ................................

    //add

      P0IFG =0; // 清除标志位   
      P0IF = 0; // 清除标志位  
      P0SEL &= (~0x02); // 设置为普通IO  
      P0DIR &= (~0x02); // 设置为输入方式  
      P0IEN |= 0x02;    // 开启中断  
      PICTL |= 0x01;    // 下降沿触发  
      IEN1 |=0X20;      // 使能P0 中断 

    }


    #pragma vector=P0INT_VECTOR     
    __interrupt void P0INT_ISR(void)  //void Key_ISR(void) //halKeyPort0Isr//P0_ISR
    {  
     
         
      //breast massager gyh
        {
          if(flag==0)
          flag=1;
        }
       P0IFG=0;   //清P0.1中断标志
       P0IF=0;

    }

    Error[Be004]: function "halKeyPort0Isr" (declared at line 664 of "C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\hal_key.c") has overlaid vector with function  
    "P0INT_ISR" (declared at line 740 of "C:\Texasen Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\hal_key.c"), second vector deleted

    编译时,可能中断向量表有冲突,不知怎么处理。


    1. 轮询你的按键状态,如果你是跟keyfob参考设计一样那种单纯按住就接地的按键,那只要轮询GPIO的输入状态就行。

    》》》》》》这个用timer去轮询按键状态。当发现有按键,就跳出。

    我动作那边不用while(1)这条代码,用什么条件能保持它一直操作那个动作。直到轮询到按键跳出。

    谢谢

    lincoln

  • yan,好

    用了while(1){ },按键时,没反应,进不去HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )。没用while(1),跟踪能进去。

    告诉我怎么处理编译时,可能中断向量表有冲突。

    谢了

    祝好

    lincoln

  • 你好,yan

       我把中断程序单独用一个文件写。

    void Key_Init(void)
    {
        /**********  按键相关设置 : P0_1  **********/    
      P0IFG =0; // 清除标志位   
      P0IF = 0; // 清除标志位  
      P0SEL &= (~0x02); // 设置为普通IO  
      P0DIR &= (~0x02); // 设置为输入方式  
      P0IEN |= 0x02;    // 开启中断  
      PICTL |= 0x01;    // 下降沿触发  
      IEN1 |=0X20;      // 使能P0 中断  
       EA=1;   
       EA=1;    
       }
    #endif  


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

        {
          if(flag==0)
          flag=1;
        }
       P0IFG=0;   //清P0.1中断标志
       P0IF=0;

    }  

    编译还是跟HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )冲突。

    原来是编译出做。在这边是中断向量表警告。

    屏蔽掉HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )就没警告。

    帮帮我,怎么处理这个冲突。

    我始终没搞清,中断进不了while(1)里面去。每次按键都是中断与轮询同时进行吗?还是中断只在某个时候才用。轮询一直用。

    谢谢

    lincoln

  • yuhua lincoln,

    P0INT_VECTOR 只能对应一个中断处理函数,你自己定义了就应该把原来工程里面的删除。

    while(1) 不要用,用了就挂起了。。。。。。用timer啊,给其他代码一点执行时间啊,你这样while(1),人家中断都没法玩了。

    osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);,类似这个,过一段时间检查一下flag,再过一段时间检查一下flag,这样就应该可以。

  • 你好,yan

      用定时始终osal_start_timerEx,能进入了。但短按键基本进不了,要长按才行,也不是每次能进去。可能原因:

    1)osal_start_timerEx占了不少时间,外部中断很难进来。

    2)osal_start_timer占了不少时间,是否对消抖时间有影响。

    3)while(1),基本外部中断进不去。内部中断是否也很难进去。

    谢谢

    祝好

    lincoln

  • yan,好

    在用定时器这种情况下,连接着的app没办法停止它。按键长按才能停。可能那里还有点问题。

    谢谢

    lincoln

  • yan,你好

       其它osalstartimer定时事件不会出现这种现象,我发现不同之处就是我这个动作是按键启动,停止是程序调用osalstartimer,其它的不是按键程序。有什么办法让它不长按停止,与app能正常停止。

    谢了

    lincoln

  • yan,你好

       其它osal_start_timerEx定时事件不会出现这种现象,我发现不同之处就是我这个动作是按键启动,停止是是按键程序调用osal_start_timerEx,其它的不是按键程序调用。有什么办法让它不长按停止,以及app能正常停止。

    谢了

    lincoln

  • yuhua lincoln,

    按键是需要去抖的,所以会用到中断+轮询的方式。

    timer是不会影响到中断的,osal_start_timerEx只是开始一个软件定时器计时。

    你可以用示波器或者逻辑分析仪看一下你按键下去GPIO的波形,长按产生中断本身就不合理,按键只有按下去一瞬间会下降沿去触发中断,当然每次是有抖动的,所以要去抖。另外建议你中断处理函数里面一进去先 HAL_ENTER_ISR(); 然后再判断一下是不是P0_1的中断标志位被置了,看一下SDK里面的hal_key.c是怎么做的就行。

  • 你好,yan

         找到原因了,这个动作是马达正反转,在正反转之间要必须延时1-2秒,否则马达刚正转就马上反转,没方法实现正反转。

    去掉延时,短按键就正常了。

    加了延时,就长按键进去。这个客户能接受。

    但app仿真停止按键,长按也进不去。这个是否有什么好办法。

    谢了

    lincoln

  • yan,好,

        由于每个马达在运行的时候的负载不同,因此第一次从同一位置启动,后面就不是同步了。当停止,或关机时,马达并没有停在同一位置,或复位回到起始位置。固件有什么办法能侦查到每个马达的位置吗?或让马达复位回到起始位置。

    祝好,

    谢谢

    lincoln