在板的设计中,使用了两个管脚来响应按键处理, 一个是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里检测按键时,会因为实际按键已经释放,所有的检测都是高电平,已经不知道是按下了哪个键进行的触发。
一天之后,在这里加了两个指示按键状态的变量,按下时记录状态,触发检测后更改为初始值,问题才得已解决。