基于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;
}