ZigBee学习之35—按键部分及系统调用时钟的2_第1页
ZigBee学习之35—按键部分及系统调用时钟的2_第2页
ZigBee学习之35—按键部分及系统调用时钟的2_第3页
ZigBee学习之35—按键部分及系统调用时钟的2_第4页
ZigBee学习之35—按键部分及系统调用时钟的2_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、#1楼主:【原创】ZigBee学习之35按键部分及系统调用时钟的分析2文章发表于:2010-02-17 23:57 /* Timer2 最为系统任务的时钟系统*/ OnboardTimerIntEnable = FALSE; HalTimerConfig (OSAL_TIMER, / 8bit timer2 HAL_TIMER_MODE_CTC, / Clear Timer on Compare HAL_TIMER_CHANNEL_SINGLE, / Channel 1 - default HAL_TIMER_CH_MODE_OUTPUT_COMPARE, / Output Compare m

2、ode OnboardTimerIntEnable, / Use interrupt Onboard_TimerCallBack); / Channel Mode/函数执行后得到系统任务时钟(HAL_TIMER_2)的配置结构: halTimerRecordhwtimerid.configured = TRUE; halTimerRecordhwtimerid.opMode = HAL_TIMER_MODE_CTC; halTimerRecordhwtimerid.channel = HAL_TIMER_CHANNEL_SINGLE; halTimerRecordhwtimerid.chann

3、elMode = HAL_TIMER_CH_MODE_OUTPUT_COMPARE; halTimerREnable = FALSE; halTimerRecordhwtimerid.callBackFunc = Onboard_TimerCallBack;/Onboard_TimerCallBack()为处理系统时钟的回调函数,这个函数什么时候会被调用呢?是个问题/一些相关宏的定义如下:/#define HAL_TIMER_MODE_CTC 0x02 / Clear Timer On Compare/#define HAL_TIMER_CHANNEL_SI

4、NGLE 0x01 / Single Channel - default/#define HAL_TIMER_CH_MODE_OUTPUT_COMPARE 0x02 / Channel Mode Output_Compare/现在系统任务时钟所需要使用的定时器已经配置好了,但是如何启动的呢?启动定时器必须要对TxCTL寄存器启动位置位才能启动啊!我们回到ZMain.c中的main()中,在InitBoard( OB_COLD );下面接着执行的是HalDriverInit()函数,在此函数中最开始就是初始化了定时器HalTimerInit();进去一看发现任然没有启动定时器!仅仅只是对定时器的

5、寄存器进行了一个别名配置而已,增加了如下的配置: halTimerRecordHW_TIMER_4.prescale = HAL_TIMER4_8_PRESCALE; halTimerRecordHW_TIMER_4.clock = HAL_TIMER_32MHZ; halTimerRecordHW_TIMER_4.prescaleVal = HAL_TIMER4_8_PRESCALE_VAL; /* Setup Timer4 Channel structure */ halTimerChannelHW_TIMER_4.TxCCTL = TCHN_T4CCTL; halTimerChannel

6、HW_TIMER_4.TxCCL = TCHN_T4CCL; halTimerChannelHW_TIMER_4.TxCCH = TCHN_T4CCH; halTimerChannelHW_TIMER_4.TxOVF = TCNH_T4OVF; halTimerChannelHW_TIMER_4.ovfbit = TCHN_T4OVFBIT; halTimerChannelHW_TIMER_4.intbit = TCHN_T4INTBIT;那么是不是初始在main()中的osal_init_system();【OSAL.c】函数中,好,那我们来看一下,是不是这里启动了系统时钟定时器。在这个函数

7、中又调用了一个函数嫌疑最大:osalTimerInit();【OSAL_Timers.c】void osalTimerInit( void )/初始化了两个变量/#define TICK_TIME 1000/#define TIMER_DECR_TIME 1 tmr_count = TICK_TIME; tmr_decr_time = TIMER_DECR_TIME; /这里是停止了系统时钟定时器OSAL_TIMER osal_timer_activate( false ); timerActive = false; osal_systemClock = 0;/看来在这个函数中也没有启动系统定

8、时器,反而调用了停止系统时钟定时器的函数,莫非是黎明前的黑暗,呵呵!接着在main()函数中找嫌疑犯!再往下是打开了总中断osal_int_enable( INTS_ALL );剩下的可能在就是osal_start_system()中启动系统时钟了,我们来找一下。/在此函数中调用了Hal_ProcessPoll ()【hal_drivers.c】void Hal_ProcessPoll () /* Timer Poll */ HalTimerTick(); /这个函数又是个跟时钟相关的函数,会不会在这里面启动系统时钟呢?来看一下 /* UART Poll */#if (defined HAL_

9、UART) && (HAL_UART = TRUE) HalUARTPoll();#endif/【hal_timer.c】void HalTimerTick (void)/前面调用的InitBoard()中已经设置halTimerREnable = FALSE;/再根据HAL_TIMER_2 -> HW Timer 4,所以会执行以下函数: if (!halTimerRecordHW_TIMER_4.intEnable) halProcessTimer4 (); /继续跟踪。这个函数在定时器发生中断的时候就会执行,因为在定时器4中断中有

10、调用此函数:HAL_ISR_FUNCTION( halTimer4Isr, T4_VECTOR )halProcessTimer4 ();void halProcessTimer4 (void) if (halTimerRecordhalTimerRemap(HAL_TIMER_2).channelMode = HAL_TIMER_CH_MODE_OUTPUT_COMPARE) if (TIMIF & TIMIF_T4CH0IF)/定时器4通道0产生中断 TIMIF &= (TIMIF_T4CH0IF); /清除中断标志 halTimerSendCallBack (HAL_TI

11、MER_2, HAL_TIMER_CHANNEL_A, HAL_TIMER_CH_MODE_OUTPUT_COMPARE);/调用前面初始化的回调函数,对系统时钟+1 if (TIMIF & TIMIF_T4CH1IF) TIMIF &= (TIMIF_T4CH1IF); halTimerSendCallBack (HAL_TIMER_2, HAL_TIMER_CHANNEL_B, HAL_TIMER_CH_MODE_OUTPUT_COMPARE); /貌似还没有看到启动系统时钟的定时器啊!呵呵别急,我们现在回过来看按键程序,我们接着分析这个函数:byte osal_start

12、_timerEx( byte taskID, UINT16 event_id, UINT16 timeout_value ) halIntState_t intState; osalTimerRec_t *newTimer; HAL_ENTER_CRITICAL_SECTION( intState ); / Hold off interrupts. /为此任务和事件填充一个新定时器数据结构,这个结构中将包含计数时间,要传递的时间,接收事件的任务 newTimer = osalAddTimer( taskID, event_id, timeout_value ); if ( newTimer )

13、 #ifdef Power_SAVING / Update timer registers osal_retune_timers(); (void)timerActive;#endif if ( timerActive = FALSE ) /这里要注意了,回想一下我们对系统时钟启动的分析,只发现停止了系统时钟,初始timerActive = FALSE,现在终于启动定时器了。而且处于开中断的状态下,这样的话当计时器溢出的时候当然会产生中断就去执行中断函数了。所以我们得出系统时钟也不是每时每刻都在运行的!(在中断方式下启动定时器) osal_timer_activate( TRUE ); HAL

14、_EXIT_CRITICAL_SECTION( intState ); / Re-enable interrupts. return ( (newTimer != NULL) ? ZSUCCESS : NO_TIMER_AVAIL ); /我们再来看一下中断服务函数,我的是用P1口:HAL_ISR_FUNCTION( halKeyPort1Isr, P1INT_VECTOR )/刚开始是对芯片版本的判断,这个部重要了,可以去掉判断直接清除P1IF标志位 if( CHVER <= REV_D ) P1IF = 0; /这个函数是清除端口每一位的子中断,然后继续进行先前的任务,即发送按键事件

15、HAL_KEY_EVENT给指定的任务 halProcessKeyInterrupt(); if( CHVER >= REV_E ) /大于版本E的清除中断后进入睡眠模式 P1IF = 0; CLEAR_SLEEP_MODE(); /注意在ZStack1.4.3-1.2.1中对于任务的管理是通过任务表来进行的,每个任务由初始化函数和事件处理函数构成,任务的初始化通过osalInitTasks()进行,然后OSAL利用任务表来调用任务函数,注意任务表中的顺序必须和任务初始化的顺序一致/任务处理函数表,在后面可以添加自己的任务处理函数【sapi.c】const pTaskEventHandl

16、eRFn tasksArr = macEventLoop, nwk_event_loop, Hal_ProcessEvent,#if defined( MT_TASK ) MT_ProcessEvent,#endif APS_event_loop, ZDApp_event_loop, SAPI_ProcessEvent;void osalInitTasks( void ) uint8 taskID = 0; tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); osal_memset( tasksEvents

17、, 0, (sizeof( uint16 ) * tasksCnt); macTaskInit( taskID+ ); nwk_init( taskID+ ); Hal_Init( taskID+ );#if defined( MT_TASK ) MT_TaskInit( taskID+ );#endif APS_Init( taskID+ ); ZDApp_Init( taskID+ ); SAPI_Init( taskID );/有一条主线:osal_set_event()将事件存入tasksEvents数组中【或者:通过HalTimerConfig()配置定时器的回调函数对指定任务和事件调用osal_start_timerEx()等指定超时时间到达后通过调用回调函数来调用osal_set_event()】系统主循环中检查到tasksEvents 数组中有事件调用相应的接收事件的函数(tasksArridx)( idx, events ) Hal_ProcessEvent()检查是否是按键事件 HalKeyPoll()得到按键值调用按键回调函数OnBoard_KeyCallback(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论