解决CC2530在zstack中无法进入P0中断的问题
最近使用CC2530控制一个超声波模块,需要使用外部中断P0接收数据,定时器来计时。裸机程序没有问题,移植进入ZSTACK的时候无法进入中断P0。
但是可以使用P1的中断。
由于业务需要只能用P0中断,就想办法解决了这个问题
主要参考链接:
ZSTACK的P0中断被协议栈使用了,所以这里要把占用P0的地方去掉,即不使用按键。
下附ZSTACK操作超声波代码,P04为外部中断输入,P05为脉冲信号输出。
以下是IO初始化与中断处理函数。其中的中断处理函数也可以使用ZSTACK自带的函数HAL_ISR_FUNCTION
#define TRIG P0_5
#define ECHO P0_4
static void GPIO_Init(void)
{
P0DIR &= ~0x10;//0000 0001
P0DIR |= 0x20; //0000 0010
TRIG = 0;
IEN1 |= 0x20;
P0IEN |= 0x10; //P00口中断使能
PICTL &= ~0x01; //P00上升沿
P0IFG &= 0x00; //P1口中断状态,如果有中断发生,相应位置1
T1CTL |= 0x08; //T1使用32分频
}
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void) //P0口中断处理函数
{
uint16 tempH = 0;
uint8 tempL = 0;
uint32 timeOutCnt = 0;
uint16 echoTime;
float distanceMM;
if(P0IFG & 0x10) //p00
{
// P0IFG &= ~0x01; //清除IO口中断标志
T1CTL |= 0x01; //启动定时器
P0IFG = 0;
while(ECHO) //等待回波引脚变为0
{
timeOutCnt++;
if(timeOutCnt > 480000) //如果超时,返回,否则会导致死机
return;
}
T1CTL &= ~0x01; //停止计数器
tempH = T1CNTH; //读取计数器值
tempL = T1CNTL;
echoTime = (tempH<<8)|tempL;
T1CNTL = 0x00; //计数器清零
if(echoTime > 100) //2cm内不测量
{
distanceMM = echoTime*0.172; //单位为mm,
//UART_SendStr((uint16)distanceMM);
UART0_Format.Command = 0x01;
UART0_Format.Data[0] = (uint16)distanceMM >> 8;
UART0_Format.Data[1] = (uint16)distanceMM;
osal_set_event(SerialApp_TaskID, SERIALAPP_SEND_EVT);
}
}
P0IF = 0;
}
以下是任务事件中的发送脉冲
if ( events & ULTRASOUND_READ_EVT )
{
TRIG = LOW;
MicroWait(10);
TRIG = HIGH;
osal_start_timerEx(SerialApp_TaskID, ULTRASOUND_READ_EVT, 500);
return ( events ^ ULTRASOUND_READ_EVT );
}
以上