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.

基于Z-STACK的键中断

Other Parts Discussed in Thread: Z-STACK

搜了一圈好像没有这个问题,如果之前有人问的话请发个链接,谢谢。

想做一个基于外部中断的按键处理函数,我的硬件图

然后我就把键初始化和键中断服务函数加进去,

void InitKey(void)

{
P0IEN |= 0x20; // P0_5 设置为中断方式 1:中断使能
PICTL |= 0x10; //下降沿触发
IEN1 |= 0x20; //允许P0口中断;
P0IFG = 0x00; //初始化中断标志位
EA = 1; //打开总中断
}

#pragma vector = P0INT_VECTOR 
__interrupt void P0_ISR(void) 

    DelayMS(10); //延时去抖
    led2 = ~led2; //改变LED1状态
    P0IFG = 0; //清中断标志 
    P0IF = 0; //清中断标志 
}

这两个函数放在我自己新建的工程当中,是可以正常工作的,但是,等我放到Z-STACK里面,

编译,出现错误

Erro[Pa045]:function "P0_ISR" has no prototype 

问题:1,Z-stack里面是否有相应的中断服务函数,可直接调用,省去上述麻烦?

         2,如何自行添加如上的中断服务函数?

再次感谢各位了!!

  • 在z-stack中的中断函数方式是:

    #define HAL_ISR_FUNCTION(f,v) 在Hal_mcu.h文件中定于了。

    你直接调用就可以,但是注意z-stack中P0口的中断函数,已经有定义了

    HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )

  • 比方说我用定时器中断,先需要定义:

    #define SEND_DATA_EVENT 0x01  //定时事件ID

    然后,osal_set_event(GenericApp_TaskID,SEND_DATA_EVENT);//设置事件

    再然后只要判断 if( events & SEND_DATA_EVENT)就行,当定时中断发生时,括号里的表达式就为真。

    上述为定时器中断大概的用法,我想问问,这个键中断是否有着跟定时器差不多的用法??

  • 你好,

    不太理解按键中断 是I/O口中断,跟定时器有什么关系?你说的是定时器中断?还是定时器定时查询?

    中断响应速度会更快,而且不需要额外的资源消耗,如果是定时器的话需要定时器一直开在那边,按键时不一定马上能响应。

  • 回复时间22:27???ti的猛士。

    简而言之,怎么用外部中断?初始化函数需不需要?中断服务函数是哪个?

    直接在这个函数  HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ) 里面写中断服务程序吗?

  • 初始化当然需要啊 你总得配置那个IO口,什么中断方式。

    如果是PO口的话,可以用这个函数。

  • 对P0口的寄存器进行配置之后,然后在 HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ) 里面写中断服务程序就可以了

  • z-stack-2.3.0-1.4.0版本,基于GenericApp例程修改

    按照两位所说,初始化IO口

    void InitKey(void)

    {
    P0IEN |= 0x20; // P0_5 设置为中断方式 1:中断使能
    PICTL |= 0x10; //下降沿触发 
    IEN1 |= 0x20; //允许P0口中断; 
    P0IFG = 0x00; //初始化中断标志位
    EA = 1; //打开总中断
    }

    然后添加 HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ) { }

    编译出现  Error[Pe020]: identifier "POINT_VECTOR" is undefined

    在hal_mcu.h找到

    #define HAL_ISR_FUNC_DECLARATION(f,v) _PRAGMA(vector=v) __near_func __interrupt void f(void)
    #define HAL_ISR_FUNC_PROTOTYPE(f,v) _PRAGMA(vector=v) __near_func __interrupt void f(void)
    #define HAL_ISR_FUNCTION(f,v) HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v)

    不知道两位看明白没?谢谢

  • 是不是书写错误?  POINT_VECTOR 应该是 P0INT_VECTOR吧?是0不是O

  • 汗,IAR里面大写字母O和数字0,小写字母l和数字1,傻傻分不清楚。

    但是麻烦又来了,出现

    Error[e27]: Entry "halKeyPort0Isr" in module Enddevice

    我明明已经在Enddevice的状态下了,看图。谢谢

  • 错误显示halKeyPort0Isr被重复定义了。你是不是自己定义了halKeyPort0Isr?hal_key.c里面已经定义了halKeyPort0Isr、

    HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ) ,你在里面修改中断服务程序就好了。

    或者你也可以屏蔽hal_key.c里面的HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ),然后自己重新编写HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )及服务程序。

  • 谢谢你,我再好好仔细琢磨

    有没有哪个官方的例程是用到P0口的外部中断的

  • 您好,Susan

    请问使用协议栈的中断服务函数的话,还需要使用RegisterForKeys( SAMPPLE_APP_TaskID ); 来注册按键事件吗?

  • VV ,您好

    最近我也在Z-STACK的例子程序上添加了按键的中断程序,

    我的io口初始化程序是这样的:

    void Init_IO_AND_LED(void)
    {
      P0INP &= ~0X32; // 设置P0口输入电路模式为上拉/下拉
      P0IEN |= 0X03; // P01/00设置为中断使能方式
      PICTL |= 0X01; // 下降沿触发
      IEN1 |= 0X20; // 开P0口总中断
      P0IFG |= 0x00; // 清中断标志
      EA = 1;
    }

    然后,我在HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )函数中添加了一个打印的语句,程序是酱紫的:

    HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
    {
      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;
      HalUARTWrite(0, "exit hal_isr\r\n", 14);
    }

    可是,我发现 板子只有在上电开机时候 才打印一次这个语句,后来再按按键也不会打印了,这就是再没有进过HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )这个函数了吗?

  • Susan 你好,关于这个 P0口的寄存器配置 在哪里设置啊,我用的协议栈是2.5.1.a版本的?我的目的是加一个P0口中断控制唤醒PM2,目前想法是:1.配置P0口寄存器;2.在 HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ) 里面有加一句   PCON = 0X01; 

    if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT)
    {
    //halProcessKeyInterrupt();
    PCON = 0X01;//我自己加的
    }

    /*
    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;
    }