概述
2019独角兽企业重金招聘Python工程师标准>>>
板子上UP、DOWN、LEFT和RIGHT 四个键原先是通过AD转换来判断的,OK键和CANCEL键是直接连接I/O的.将电容C20和电子R13去掉,将R4改成10K电阻,那么RIGHT键也将是直接连接I/O了。接下来,我将通过一系列的改动,将OK、CANCEL和RIGHT三个键改成中断方式来查询其状态。
首先,要使能中断方式查询按键状态。在OnBoard.c文件,修改InitBoard()函数,如下面红色部分所示:
void InitBoard( byte 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
{
#ifdef ZTOOL_PORT
MT_SysResetInd();
#endif
//*********** 自己修改 ******************************
/* Initialize Key stuff */
//OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;//DISABLE 按键中断
OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;//使能按键中断
//****************************************************
HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
}
}//end of InitBoard( byte level )
由于CANCEL、OK和RIGHT键分别连接在P0的4、5、6三个引脚,所以还需要修改P0口的初始化。CANCEL和OK两键已经初始化过了,接下来要添加RIGHT键的初始化。先要定义几个宏哦。在hal_key.c文件,添加:
//******* 自己添加 **************
/* P0.6_ADC_KEY is at P0.6 */
#define HAL_KEY_SW_8_PORT P0
#define HAL_KEY_SW_8_BIT BV(6)
#define HAL_KEY_SW_8_SEL P0SEL
#define HAL_KEY_SW_8_DIR P0DIR
/* edge interrupt */
#define HAL_KEY_SW_8_EDGEBIT BV(0)
#define HAL_KEY_SW_8_EDGE HAL_KEY_FALLING_EDGE
/*P0.6_ADC_KEY interrupts */
#define HAL_KEY_SW_8_IEN P0
#define HAL_KEY_SW_8_IENBIT BV(6)
#define HAL_KEY_SW_8_ICTL P0IEN
#define HAL_KEY_SW_8_ICTLBIT BV(6)
#define HAL_KEY_SW_8_PXIFG P0IFG
//**********************************
这几个宏定义很重要,可以参考CANCEL键和OK键的宏定义进行定义。
接下来,也是在hal_key.c文件,修改 HalKeyInit( void )函数,如下面红色部分所示:
void HalKeyInit( void )
{
/* Initialize previous key to 0 */
halKeySavedKeys = 0;
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_SW_7_SEL &= ~(HAL_KEY_SW_7_BIT); /* Set pin function to GPIO */
HAL_KEY_SW_7_DIR &= ~(HAL_KEY_SW_7_BIT); /* Set pin direction to Input */
//********** 自己添加 *********************
//P0.6_ADC_KEY
HAL_KEY_SW_8_SEL &= ~(HAL_KEY_SW_8_BIT); /* Set pin function to GPIO */
HAL_KEY_SW_8_DIR &= ~(HAL_KEY_SW_8_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 */
/* Initialize callback function */
pHalKeyProcessFunction = NULL;
/* Start with key is not configured */
HalKeyConfigured = FALSE;
}
另外,还要修改HalKeyConfig (bool interruptEnable, halKeyCBack_t cback)函数,如下面红色部分所示:
void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback)
{
/* Enable/Disable Interrupt or */
Hal_KeyIntEnable = interruptEnable;
/* Register the callback fucntion */
pHalKeyProcessFunction = cback;
/* 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
PICTL &= ~(HAL_KEY_SW_7_EDGEBIT); /* Clear the edge bit */
/* For falling edge, the bit must be set. */
#if (HAL_KEY_SW_7_EDGE == HAL_KEY_FALLING_EDGE)
PICTL |= HAL_KEY_SW_7_EDGEBIT;
#endif
//************** 自己添加 ****************
//P0.6_ADC_KEY
PICTL &= ~(HAL_KEY_SW_8_EDGEBIT); /* Clear the edge bit */
/* For falling edge, the bit must be set. */
#if (HAL_KEY_SW_8_EDGE == HAL_KEY_FALLING_EDGE)
PICTL |= HAL_KEY_SW_8_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);
HAL_KEY_SW_7_ICTL |= HAL_KEY_SW_7_ICTLBIT;
HAL_KEY_SW_7_IEN |= HAL_KEY_SW_7_IENBIT;
HAL_KEY_SW_7_PXIFG = ~(HAL_KEY_SW_7_BIT);
//********** 自己添加 *******************
//P0.6_ADC_KEY
HAL_KEY_SW_8_ICTL |= HAL_KEY_SW_8_ICTLBIT;//使能P0.6中断
HAL_KEY_SW_8_IEN |= HAL_KEY_SW_8_IENBIT;
HAL_KEY_SW_8_PXIFG = ~(HAL_KEY_SW_8_BIT); //清中断标记
//****************************************
/* Rising/Falling edge configuratinn */
// 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)
// 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 */
}
}
else /* Interrupts NOT enabled */
{
HAL_KEY_SW_6_ICTL &= ~(HAL_KEY_SW_6_ICTLBIT); /* don't generate interrupt */
HAL_KEY_SW_6_IEN &= ~(HAL_KEY_SW_6_IENBIT); /* Clear interrupt enable bit */
HAL_KEY_SW_7_ICTL &= ~(HAL_KEY_SW_7_ICTLBIT); /* don't generate interrupt */
HAL_KEY_SW_7_IEN &= ~(HAL_KEY_SW_7_IENBIT); /* Clear interrupt enable bit */
osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_POLLING_VALUE); /* Kick off polling */
}
/* Key now is configured */
HalKeyConfigured = TRUE;
}
接下来,还要修改两个重要的函数:HalKeyPoll (void) 和 halProcessKeyInterrupt (void)。分别如下面红色部分所示:
void HalKeyPoll (void)
{
uint8 keys = 0;
if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT)) /* Key is active low *///OK键,P0.5
{
keys |= HAL_KEY_SW_6;
}
if (!(HAL_KEY_SW_7_PORT & HAL_KEY_SW_7_BIT)) /* Key is active low *///CANCEL键,P0.4
{
keys |= HAL_KEY_SW_7;
}
//***************** 自己添加 *****************
if (!(HAL_KEY_SW_8_PORT & HAL_KEY_SW_8_BIT)) /* Key is active low *///,P0.6
{
keys |= HAL_KEY_SW_8;
}
//********************************************
// if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT)) /* Key is active HIGH */
{
// keys |= halGetJoyKeyInput();//通过AD转换来判断按键
}
/* 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 */
return;
}
/* Store the current keys for comparation next time */
halKeySavedKeys = keys;
}
else//如果使能了按键中断
{
/* Key interrupt handled here */
asm("nop");
}
/* Invoke Callback if new keys were depressed */
if (keys && (pHalKeyProcessFunction))
{
(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
}
}//end of HalKeyPoll (void)
void halProcessKeyInterrupt (void)
{
bool valid=FALSE;
if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT) /* Interrupt Flag has been set *///P0.5
{
HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); /* Clear Interrupt Flag */
valid = TRUE;
}
if (HAL_KEY_SW_7_PXIFG & HAL_KEY_SW_7_BIT) /* Interrupt Flag has been set *///P0.4
{
HAL_KEY_SW_7_PXIFG = ~(HAL_KEY_SW_7_BIT); /* Clear Interrupt Flag */
valid = TRUE;
}
//********** 自己添加 ****************
if (HAL_KEY_SW_8_PXIFG & HAL_KEY_SW_8_BIT) /* Interrupt Flag has been set *///P0.4
{
HAL_KEY_SW_8_PXIFG = ~(HAL_KEY_SW_8_BIT); /* Clear Interrupt Flag */
valid = TRUE;
}
//************************************
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 */
valid = TRUE;
}
if (valid)
{
osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);
}
}
P0口外部中断的函数,要修改一下if语句的判断条件,否则就前功尽弃了。如下面红色部分所示:
HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
{
// if ((HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT)||(HAL_KEY_SW_7_PXIFG & HAL_KEY_SW_7_BIT))
//自己修改
if ((HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT)||(HAL_KEY_SW_7_PXIFG & HAL_KEY_SW_7_BIT) || (HAL_KEY_SW_8_PXIFG & HAL_KEY_SW_8_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;
}
最后,别忘了修改应用层的SerialApp.c文件中的SerialApp_HandleKeys( uint8 shift, uint8 keys ) 函数。因为,每一个按键要对应一个功能,那么就在这里添加功能吧。修改如下面红色部分所示:
void SerialApp_HandleKeys( uint8 shift, uint8 keys )
{
zAddrType_t txAddr;
if ( shift )
{
if ( keys & HAL_KEY_SW_1 )
{
}
if ( keys & HAL_KEY_SW_2 )
{
}
if ( keys & HAL_KEY_SW_3 )
{
}
if ( keys & HAL_KEY_SW_4 )
{
}
}
else
{
if ( keys & HAL_KEY_SW_1 )//UP 键
{
asm("nop");//自己添加
}
if ( keys & HAL_KEY_SW_2 )//RIGHT 键
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate an End Device Bind Request for the mandatory endpoint
txAddr.addrMode = Addr16Bit;
txAddr.addr.shortAddr = 0x0000; // Coordinator
ZDP_EndDeviceBindReq( &txAddr, NLME_GetShortAddr(),
SerialApp_epDesc.endPoint,
SERIALAPP_PROFID,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
FALSE );
}
if ( keys & HAL_KEY_SW_3 )//DOWN 键
{
asm("nop");//自己添加
}
if ( keys & HAL_KEY_SW_4 )//LEFT 键
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate a Match Description Request (Service Discovery)
txAddr.addrMode = AddrBroadcast;
txAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
ZDP_MatchDescReq( &txAddr, NWK_BROADCAST_SHORTADDR,
SERIALAPP_PROFID,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
FALSE );
}
//*********** 自己添加 *********
if( keys & HAL_KEY_SW_6)//OK键,P0.5
{
asm("nop");
//添加按键服务程序
}
if( keys & HAL_KEY_SW_7)//CANCEL键,P0.4
{
asm("nop");
//添加按键服务程序
}
if( keys & HAL_KEY_SW_8)//P0.6_ADC_KEY 键(对应开发板上的RIGHT键)
{
asm("nop");
//添加按键服务程序
}
//*******************************
}
}//end of SerialApp_HandleKeys( uint8 shift, uint8 keys )
至此,就修改完成了。别忘了保存文件哦,嘿嘿。
转载于:https://my.oschina.net/yuyang/blog/315602
最后
以上就是完美香烟为你收集整理的Zigbee 协议栈(CC2530开发板)--中断方式查询按键的全部内容,希望文章能够帮你解决Zigbee 协议栈(CC2530开发板)--中断方式查询按键所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复