完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
原文链接:http://www.kaleidscope.cn:1020/archives/1056
Zigbee协议栈中如果要实现一个定时事件或者延时的话,有很多种方法,定时事件呢其实就是我们熟悉的使用定时器来定时,产生定时事件,当然也可以用来延时。 1、协议栈定时器HaltimerConfig ZigBee协议栈提供了定时器的使用接口,在hal层调用HalTimerConfig即可配置使用,而定时器2被协议栈占用了,所以只有使用1、3、4三个定时器。 在hal_timer.h中我们可以看到几个定时器的定义: /* Timer ID definitions */ #define HAL_TIMER_0 0x00 // 8bit timer #define HAL_TIMER_1 0x01 // 16bit Mac timer #define HAL_TIMER_2 0x02 // 8bit timer #define HAL_TIMER_3 0x03 // 16bit timer #define HAL_TIMER_MAX 4 // Max number of timer 所以和硬件中的定时器是有区别的,经过了映射,这里需要注意一下。 * HAL_TIMER_0 –> HW Timer 3 8bit * HAL_TIMER_2 –> HW Timer 4 8bit * HAL_TIMER_3 –> HW Timer 1 16bit 如果我们要使用协议栈的定时器进行相关操作,只需进行定时器的配置即可: extern uint8 extern uint8 HalTimerConfig ( uint8 timerId,uint8 opMode,uint8 channel,uint8 channelMode,bool intEnable,halTimerCBack_t cback ); opMode – Operation mode操作方式共3种 * channel – Channel where the counter operates on选择通道,对应IO口 * channelMode – Mode of that channel通道的模式 * intEnable –可中断 * cBack – Pointer to the callback function 中断函数 然后在回调函数中进行处理相关事件即可。 void timer_callback(uint8 timerId, uint8 channel, uint8 channelMode); 2、使用寄存器直接操作 直接使用寄存器就更简单了,就把CC2530当做一个单片机用就可以了,这里我拿了我以前写的代码给大家演示,注释有错的地方请忽略,大概就这样吧。 void InitT3(void) [ T3CTL |= 0x08 ; //开溢出中断 T3IE = 1; //开总中断和T3中断 T3CTL|=0X12; //,128/16000000*N=0.5S,N=65200 T3CC0 = 0x01; T3CTL &= ~0X03; //自动重装 00->0xff T3CTL |=0X10; //启动 ] void timer1Init(void) [/*设置定时器T1,128分频,模模式,从0计数到T1CC0*/ T1CTL |= 0x0E; /*装入定时器初值(比较值)*/ T1CC0L = 0x01; T1CC0H = 0x00; /*设置捕获比较通道0为比较模式,用以触发中断*/ T1CCTL0 ^=BIT(2); /*使能Timer1中断*/ T1IE = 1; T1CTL |= 0x03; //开启定时器 /*开启总中断*/ ] #pragma vector=T1_VECTOR __near_func __interrupt void t1_irq(void) [ //做一点别的事情 ] #pragma vector=T3_VECTOR __interrupt void T3_IRQ(void) [ IRCON = 0x00; //清中断标志, 也可由硬件自动完成 ] 3、使用OSAL_Timer延时或定时事件 假如我们现在需要20s翻转一次led灯,那么我们可以使用 uint8 osal_set_event( uint8 task_id, uint16 event_flag )这个函数设定一个事件,下一次协议栈轮询的时候就会执行相应的事件,在GenericApp_ProcessEvent中我们可以添加自己的事件: if ( events & APP_LED_TOGGLE ) [ //执行LED灯的翻转 return (events ^ APP_LED_TOGGLE); ] 如果你这个使用调用osal_set_event( your_task_id, APP_LED_TOGGLE )的话,就会执行一次LED灯的翻转,但是不会有第二次(注意,这里task_id需要填写你自己的task_id),如果我们需要每过20s就翻转一次,那我们还需要在事件处理的地方添加另一行代码即可: osal_start_timerEx( your_task_id,,APP_LED_TOGGLE,20000 ); 最后一个参数是定时时间,ms为单位,APP_LED_TOGGLE是你自己定义的任务,其中最高位(0x08000,SYS_EVENT_MSG)系统保留,用户可以使用的事件有15个。这个大家自己找个地方宏定义下就OK了。现在我们的代码就变成了这样: if ( events & APP_LED_TOGGLE ) [ //执行LED灯的翻转 osal_start_timerEx( your_task_id,,APP_LED_TOGGLE,20000 ); return (events ^ APP_LED_TOGGLE); ] 如此,20s后LED灯又会翻转一次,达到了定时事件的效果。同样,也可以用这个方法来延时。 总的来说,协议栈中使用定时器还是比较容易的,基本的用法就这三个,灵活的运用,一般的问题都可以解决。当然,在使用定时器的时候还需要注意,在PM3模式下定时器可能会不准的问题,我在之前的帖子中有提到过,是因为PM3模式下高频晶振已经不起振了,所以我们没法使用。 欢迎大家关注我的个人微信订阅号[IOT物联网世界],更多物联网好玩儿的精彩资讯等你来看。
|
|
相关推荐
2个回答
|
|
讲解的很全面,谢谢。
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
336 浏览 1 评论
529 浏览 2 评论
NA555DR VCC最低电压需要在5V供电,为什么用3.3V供电搭了个单稳态触发器也使用正常?
774 浏览 3 评论
MSP430F249TPMR出现高温存储后失效了的情况,怎么解决?
651 浏览 1 评论
对于多级放大电路板,在PCB布局中,电源摆放的位置应该注意什么?
1130 浏览 1 评论
AT32F407在USART2 DMA发送数据时,接包接到了要发送的数据,程序还是处于等待传输完成的标识判断中,为什么?
58浏览 29评论
140浏览 23评论
请问下tpa3220实际测试引脚功能和官方资料不符,哪位大佬可以帮忙解答下
252浏览 20评论
请教下关于TAS5825PEVM评估模块原理图中不太明白的地方,寻求答疑
201浏览 14评论
两个TMP117传感器一个可以正常读取温度值,一个读取的值一直是0,为什么?
57浏览 13评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 08:56 , Processed in 0.887739 second(s), Total 81, Slave 65 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号