解决功能键P2_0,不响应动作的问题

在板的设计中,使用了两个管脚来响应按键处理, 一个是S1,即P0.1,另一个是S2,即P2.0,这个管脚在ZStack中定义为摇杆,因需要将其配置为按键。在系统的按键配置中,需要处理如下:

1,对按键的响应方式,一种是轮询的方式,另一种是中断触发,本节使用的触发方式,则需要配置中断、上升沿下降沿等的处理,需要对OnBoard.c进行更改:

void InitBoard( uint8 level )
{
  if ( level == OB_COLD )
  {
    // IAR does not zero-out this byte below the XSTACK.
    *(uint8 *)0x0 = 0;
    // Interrupts off
    osal_int_disable( INTS_ALL );
    // Check for Brown-Out reset
    ChkReset();
  }
  else  // !OB_COLD
  {
    /* Initialize Key stuff */
    HalKeyConfig(HAL_KEY_INTERRUPT_ENABLE, OnBoard_KeyCallback);
  }
}

在以上代码中,最后一句的 HAL_KEY_INTERRUPT_ENABLE,表示为中断触发,如果为 HAL_KEY_INTERRUPT_DISABLE,则为轮询。

2,对启用了中断触发的键盘进行配置,在hal_key.c中的配置 HalKeyConfig:

  /* Determine if interrupt is enable or not */
  if (Hal_KeyIntEnable)
  {
    /* Rising/Falling edge configuratinn */

    PICTL &= ~(HAL_KEY_SW_6_EDGEBIT);    /* Clear the edge bit */
    /* For falling edge, the bit must be set. */
  #if (HAL_KEY_SW_6_EDGE == HAL_KEY_FALLING_EDGE)
    PICTL |= HAL_KEY_SW_6_EDGEBIT;
  #endif

    /* Interrupt configuration:
     * - Enable interrupt generation at the port
     * - Enable CPU interrupt
     * - Clear any pending interrupt
     */
    HAL_KEY_SW_6_ICTL |= HAL_KEY_SW_6_ICTLBIT;
    HAL_KEY_SW_6_IEN |= HAL_KEY_SW_6_IENBIT;
    HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT);

    /* Rising/Falling edge configuratinn */
    //此处做了更改
    PICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT);    /* Clear the edge bit */
    // HAL_KEY_JOY_MOVE_ICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT);    /* Clear the edge bit */
    /* For falling edge, the bit must be set. */
  #if (HAL_KEY_JOY_MOVE_EDGE == HAL_KEY_FALLING_EDGE)
    PICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;
    // HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;
  #endif


    /* Interrupt configuration:
     * - Enable interrupt generation at the port
     * - Enable CPU interrupt
     * - Clear any pending interrupt
     */
    HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_ICTLBIT;
    HAL_KEY_JOY_MOVE_IEN |= HAL_KEY_JOY_MOVE_IENBIT;
    HAL_KEY_JOY_MOVE_PXIFG = ~(HAL_KEY_JOY_MOVE_BIT);


    /* Do this only after the hal_key is configured - to work with sleep stuff */
    if (HalKeyConfigured == TRUE)
    {
      osal_stop_timerEx(Hal_TaskID, HAL_KEY_EVENT);  /* Cancel polling if active */
    }

K6为S1,摇杆的为S2,两个参数配置是相同的。

3,这两个键的触发函数,也都是在同一个文件中:

/***************************************************************************************************
 *                                    INTERRUPT SERVICE ROUTINE
 ***************************************************************************************************/

/**************************************************************************************************
 * @fn      halKeyPort0Isr
 *
 * @brief   Port0 ISR
 *
 * @param
 *
 * @return
 **************************************************************************************************/
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();
}


/**************************************************************************************************
 * @fn      halKeyPort2Isr
 *
 * @brief   Port2 ISR
 *
 * @param
 *
 * @return
 **************************************************************************************************/
HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR )
{
  HAL_ENTER_ISR();
  
  if (HAL_KEY_JOY_MOVE_PXIFG & HAL_KEY_JOY_MOVE_BIT)
  {
    halProcessKeyInterrupt();
  }

  /*
    Clear the CPU interrupt flag for Port_2
    PxIFG has to be cleared before PxIF
    Notes: P2_1 and P2_2 are debug lines.
  */
  HAL_KEY_JOY_MOVE_PXIFG = 0;
  HAL_KEY_CPU_PORT_2_IF = 0;

  CLEAR_SLEEP_MODE();
  HAL_EXIT_ISR();
}

从代码中可以看出,当检测到有键按下时,都是触发了 halProcessKeyInterrupt。

4,对按下时所使用长短按等,在这段代码中处理就可以了:

/**************************************************************************************************
 * @fn      halProcessKeyInterrupt
 *
 * @brief   Checks to see if it's a valid key interrupt, saves interrupt driven key states for
 *          processing by HalKeyRead(), and debounces keys by scheduling HalKeyRead() 25ms later.
 *
 * @param
 *
 * @return
 **************************************************************************************************/
void halProcessKeyInterrupt (void)
{
  if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT)  /* Interrupt Flag has been set */
  {
    HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); /* Clear Interrupt Flag */
  }

  
  if (HAL_KEY_JOY_MOVE_PXIFG & HAL_KEY_JOY_MOVE_BIT)  /* Interrupt Flag has been set */
  {
    HAL_KEY_JOY_MOVE_PXIFG = ~(HAL_KEY_JOY_MOVE_BIT); /* Clear Interrupt Flag */
  }
…

……
    osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);
}

出现的问题是,在处理长短按的过程中,使用了上升沿与下降沿的处理,使用上拉电阻使其为高电平,在按下按键时才为低电平,处理过程是下降沿时开始计时,上升沿时计时结束,释放,再执行 osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE),这样在 hal_key.c中的HalKeyPoll里检测按键时,会因为实际按键已经释放,所有的检测都是高电平,已经不知道是按下了哪个键进行的触发。

一天之后,在这里加了两个指示按键状态的变量,按下时记录状态,触发检测后更改为初始值,问题才得已解决。

上一篇:[LeetCode] 1109. Corporate Flight Bookings


下一篇:Zabbix 上Windows性能监控