ZigBee协议学习之InitBoard.docx
《ZigBee协议学习之InitBoard.docx》由会员分享,可在线阅读,更多相关《ZigBee协议学习之InitBoard.docx(21页珍藏版)》请在冰点文库上搜索。
ZigBee协议学习之InitBoard
ZigBee2006协议学习之InitBoard()
//初始化板上的IO
InitBoard(OB_COLD);
//参数【OnBoard.h】#defineOB_COLD0#defineOB_WARM1#defineOB_READY2
//【OnBoard.c】
voidInitBoard(bytelevel)
{
if(level==OB_COLD)
//关中断,最初的时候已经见过了
osal_int_disable(INTS_ALL);
//关闭所有的LED,调用了LED设置函数
HalLedSet(HAL_LED_ALL,HAL_LED_MODE_OFF);
//LED设置函数【hal_led.c】
//【hal_led.h】
//#defineHAL_LED_ALL(HAL_LED_1|HAL_LED_2|HAL_LED_3|HAL_LED_4)
//我这里呢只有两个LED,所以可以屏蔽掉LED3,LED4,或者将后两个LED也映射到
//前面两个LED(其实就是宏定义啦)
//#defineHAL_LED_MODE_OFF0x00
//#defineHAL_LED_MODE_ON0x01
//#defineHAL_LED_MODE_BLINK0x02
//#defineHAL_LED_MODE_FLASH0x04
//#defineHAL_LED_MODE_TOGGLE0x08
uint8HalLedSet(uint8leds,uint8mode)
#if(defined(BLINK_LEDS))&&(HAL_LED==TRUE)
//前提条件是定义了闪烁LED和LED硬件驱动服务使能;
//HAL_LED定义在【hal_board_cfg.h】
//#ifndefHAL_LED
//#defineHAL_LEDTRUE//当设为FALSE时就不使用LED
//#endif
//#if(!
definedBLINK_LEDS)&&(HAL_LED==TRUE)
//#defineBLINK_LEDS
uint8led;
HalLedControl_t*sts;
//LED控制结构体
typedefstruct{
uint8mode;/*操作模式*/
uint8todo;/*剩余的闪烁周期数*/
uint8onPct;/*周期中所占的比例*/
uint16time;/*开关周期时间(msec)*/
uint32next;/*下次改变的时间*/
}HalLedControl_t;
switch(mode)
caseHAL_LED_MODE_BLINK:
HalLedBlink(leds,1,HAL_LED_DEFAULT_DUTY_CYCLE,HAL_LED_DEFAULT_FLASH_TIME);
//LED设置的一些默认参数【hal_led.h】
#defineHAL_LED_DEFAULT_MAX_LEDS4
#defineHAL_LED_DEFAULT_DUTY_CYCLE5
#defineHAL_LED_DEFAULT_FLASH_COUNT50
#defineHAL_LED_DEFAULT_FLASH_TIME1000
//LED闪烁函数【hal_led.c】
voidHalLedBlink(uint8leds,uint8numBlinks,uint8percent,uint16period)
//同样先判断是否启用了LED并且使用LED闪烁功能
if(leds&&percent&&period)
//判断参数的有效性,percent参数指明一个周期中LED将开启的时间
if(percent<100)//如果一个周期中开启时间小于100%
led=HAL_LED_1;
leds&=HAL_LED_ALL;
//屏蔽掉不想要操作的LED
sts=HalLedStatusControl.HalLedControlTable;
//HalLedStatusControl是事先定义好的一个结构体
typedefstruct
HalLedControl_tHalLedControlTable【HAL_LED_DEFAULT_MAX_LEDS】;
uint8sleepActive;
}HalLedStatus_t;
//#defineHAL_LED_DEFAULT_MAX_LEDS4
//#ifdefBLINK_LEDS
//staticHalLedStatus_tHalLedStatusControl;
while(leds)
//这个循环主要是对传进来的每一个LED进行独立的设置,比如传进来的是需要设置
//LED1和LED2,那么此循环会先设置LED1然后再设置LED2
if(leds&led)//检测当前LED是否是需要设置的
preBlinkState|=(led&HalLedState);//储存目前的额LED状态
//staticuint8preBlinkState;
sts->mode=HAL_LED_MODE_OFF;/*关闭先前的模式*/
sts->time=period;/*Timeforoneon/offcycle*/
sts->onPct=percent;/*%ofcycleLEDison*/
sts->todo=numBlinks;/*Numberofblinkcycles*/
if(!
numBlinks)sts->mode|=HAL_LED_MODE_FLASH;
//如果规定的次数未达到则继续闪烁
sts->next=osal_GetSystemClock();/*Startnow*/
//读取当前系统时钟【OSAL_Timers.c】
//uint32osal_GetSystemClock(void)
//{
//return(osal_systemClock);
//}
//staticuint32osal_systemClock;
//这样看来第一次运行的时候osal_systemClock=0,系统中应该启动了定时器,
//用来记录系统运行时间。
sts->mode|=HAL_LED_MODE_BLINK;/*Enableblinking*/
leds^=led;//屏蔽掉已设置好的这个LED
}
led<<=1;//检测下一个LED
sts++;
}//真的是高手才能写出的函数啊!
自叹,C语言编程能力还差的远啊
osal_set_event(Hal_TaskID,HAL_LED_BLINK_EVENT);
//【hal_drivers.h】
//#defineHAL_LED_BLINK_EVENT0x0002
//externuint8Hal_TaskID;
//此函数为用户设置任务标志【OSAL.c】
//第一个参数是任务ID,第二个参数是要设置的事件
byteosal_set_event(bytetask_id,UINT16event_flag)
{//只有当任务ID小于总任务数时才继续执行,也就是说只有当此为有效任务才执行。
if(task_id{halIntState_tintState;//【hal_mcu.h】其实就是一个无符号字符类型//typedefunsignedcharhalIntState_t;HAL_ENTER_CRITICAL_SECTION(intState);//维持全局中断状态//【hal_mcu.h】#defineHAL_ENTER_CRITICAL_SECTION(x)st(x=EA;HAL_DISABLE_INTERRUPTS();)//保存当前全局中断状态,然后关闭全局中断#defineHAL_EXIT_CRITICAL_SECTION(x)st(EA=x;)#defineHAL_CRITICAL_STATEMENT(x)st(halIntState_ts;HAL_ENTER_CRITICAL_SECTION(s);x;HAL_EXIT_CRITICAL_SECTION(s);)tasksEvents【task_id】|=event_flag;//Stufftheeventbit(s)//【sapi.c】//uint16*tasksEvents;HAL_EXIT_CRITICAL_SECTION(intState);//Releaseinterrupts}elsereturn(INVALID_TASK);//如果任务ID超出返回则返回任务无效//返回值类型定义在【ZComDef.h】//#defineINVALID_TASK1return(ZSUCCESS);};//【OSAL_Tasks.h】//事件处理函数原型:typedefunsignedshort(*pTaskEventHandlerFn)(unsignedchartask_id,unsignedshortevent);//定义事件处理函数的函数指针类型//【sapi.c】constpTaskEventHandlerFntasksArr【】={macEventLoop,nwk_event_loop,Hal_ProcessEvent,#ifdefined(MT_TASK)MT_ProcessEvent,#endifAPS_event_loop,ZDApp_event_loop,SAPI_ProcessEvent//tasksArr中任务事件循环中的顺序必须和osalInitTask中任务的初始化顺序一致constuint8tasksCnt=sizeof(tasksArr)/sizeof(tasksArr【0】);//得到任务数}Else//如果点亮时间百分比超过100%也就相当于常亮了,就执行LED常亮的设置{HalLedSet(leds,HAL_LED_MODE_ON);//【hal_led.c】uint8HalLedSet(uint8leds,uint8mode){#if(defined(BLINK_LEDS))&&(HAL_LED==TRUE)//一样的前提是开始了LED硬件驱动服务uint8led;HalLedControl_t*sts;switch(mode)//检测要切换的LED模式{caseHAL_LED_MODE_BLINK:HalLedBlink(leds,1,HAL_LED_DEFAULT_DUTY_CYCLE,HAL_LED_DEFAULT_FLASH_TIME);break;//如果是闪烁模式,则将指定的LED闪烁一次,点亮时间默认为5%,闪烁周期是1S//【hal_led.h】#defineHAL_LED_DEFAULT_MAX_LEDS4#defineHAL_LED_DEFAULT_DUTY_CYCLE5#defineHAL_LED_DEFAULT_FLASH_COUNT50#defineHAL_LED_DEFAULT_FLASH_TIME1000caseHAL_LED_MODE_FLASH:/*Defaultflash,Ntimes,D%dutycycle*/HalLedBlink(leds,HAL_LED_DEFAULT_FLASH_COUNT,HAL_LED_DEFAULT_DUTY_CYCLE,HAL_LED_DEFAULT_FLASH_TIME);break;//如果是连闪模式,则将指定的LED闪烁50次,点亮时间默认为5%,闪烁周期是1ScaseHAL_LED_MODE_ON:caseHAL_LED_MODE_OFF:caseHAL_LED_MODE_TOGGLE://如果是开、关、切换模式,则分别一个个的操作指定的LEDled=HAL_LED_1;leds&=HAL_LED_ALL;sts=HalLedStatusControl.HalLedControlTable;while(leds){if(leds&led){if(mode!=HAL_LED_MODE_TOGGLE){sts->mode=mode;/*ONorOFF*/}else{sts->mode^=HAL_LED_MODE_ON;/*Toggle*///开关的切换,利用了和1相异或为取反的特性。到这里为止还只是设置了LED的//模式,并没有真正的对LED进行开关的操作,也就是说LED并没有演示出效果。}HalLedOnOff(led,sts->mode);//这个函数是对LED进行开关操作的真正的函数了,这个函数执行完后应该能看到//LED状态的变化。列举程序中部分段落(因为其他段落都差不多呵呵)【hal_led.c】voidHalLedOnOff(uint8leds,uint8mode){if(leds&HAL_LED_1)//检测是否是LED1{if(mode==HAL_LED_MODE_ON)//检测开关模式{HAL_TURN_ON_LED1();//点亮LED1}else{HAL_TURN_OFF_LED1();}}…………if(mode){HalLedState|=leds;}else{HalLedState&=~leds;}//此用来记住当前操作的LED的状态,如果是点亮的就把HalLedState中相应的位置位,否则清零leds^=led;}led<<=1;sts++;}break;default:break;}#elif(HAL_LED==TRUE)LedOnOff(leds,mode);#endif/*BLINK_LEDS&&HAL_LED*/return(HalLedState);//返回的是操作了的LED的状态,每个LED在此状态中用1位来表示}//通过上面程序的解读我发现,到目前为止对LED的操作真正实现的只有开、关、切换,}//所谓的闪烁只是调用了一个系统事件设置函数}//osal_set_event(Hal_TaskID,HAL_LED_BLINK_EVENT);难道这都是通过系统事件来//实现的?因为闪烁涉及到了时间占空比,估计还调用了定时器,那有可能还用到了中断,//嗯,有可能。先接着分析下面的函数//CheckforBrown-OutresetChkReset();//检测重启原因【OnBoard.c】voidChkReset(void){uint8led;uint8rib;//Isolateresetindicatorbitsrib=SLEEP&LRESET;//得到SLEEP中的RST状态【hal_mcu.h】//#defineLRESET0x18//#defineRESETPO0x00//上电重启//#defineRESETEX0x08//外部重启//#defineRESETWD0x10//看门狗重启if(rib==RESETPO)//重启的原因【OnBoard.h】{//PutcodeheretohandlePower-Onreset}elseif(rib==RESETEX){//PutcodeheretohandleExternalreset}elseif(rib==RESETWD){//PutcodeheretohandleWatchDogreset}else//未知的重启原因,闪烁LED指示{HAL_DISABLE_INTERRUPTS();led=HAL_LED_4;while(1){HalLedSet(led,HAL_LED_MODE_ON);MicroWait(62500);MicroWait(62500);HalLedSet(led,HAL_LED_MODE_OFF);MicroWait(37500);MicroWait(37500);if(!(led>>=1))led=HAL_LED_4;}}}/*Timer2forOsaltimer*///设置OSAL的时钟OnboardTimerIntEnable=FALSE;HalTimerConfig(OSAL_TIMER,//8bittimer2HAL_TIMER_MODE_CTC,//ClearTimeronCompareHAL_TIMER_CHANNEL_SINGLE,//Channel1-defaultHAL_TIMER_CH_MODE_OUTPUT_COMPARE,//OutputComparemodeOnboardTimerIntEnable,//UseinterruptOnboard_TimerCallBack);//ChannelMode//【OnBoard.h】//使用指定的定时器#defineOSAL_TIMERHAL_TIMER_2//【hal_timer.h】//#defineHAL_TIMER_00x00//8bittimer//#defineHAL_TIMER_10x01//16bitMactimer//#defineHAL_TIMER_20x02//8bittimer//#defineHAL_TIMER_30x03//16bittimer//#defineHAL_TIMER_MAX4//Maxnumberoftimer//定时器的操作模式//#defineHAL_TIMER_MODE_NORMAL0x01//NormalMode//#defineHAL_TIMER_MODE_CTC0x02//ClearTimerOnCompare//#defineHAL_TIMER_MODE_MASK(HAL_TIMER_MODE_NORMAL|HAL_TIMER_MODE_CTC)//定时器通道定义//#defineHAL_TIMER_CHANNEL_SINGLE0x01//SingleChannel-default//#defineHAL_TIMER_CHANNEL_A0x02//ChannelA//#defineHAL_TIMER_CHANNEL_B0x04//ChannelB//#defineHAL_TIMER_CHANNEL_C0x08//ChannelC//#defineHAL_TIMER_CHANNEL_MASK(HAL_TIMER_CHANNEL_SINGLE|\HAL_TIMER_CHANNEL_A|\HAL_TIMER_CHANNEL_B|\HAL_TIMER_CHANNEL_C)//通道模式//#defineHAL_TIMER_CH_MODE_INPUT_CAPTURE0x01//ChannelModeInput-Capture//#defineHAL_TIMER_CH_MODE_OUTPUT_COMPARE0x02//ChannelModeOutput_Compare//#defineHAL_TIMER_CH_MODE_OVERFLOW0x04//ChannelModeOverflow//#defineHAL_TIMER_CH_MODE_MASK(HAL_TIMER_CH_MODE_INPUT_CAPTURE|\HAL_TIMER_CH_MODE_OUTPUT_COMPARE|\HAL_TIMER_CH_MODE_OVERFLOW)//更新定时器的函数【OnBoard.c】voidOnboard_TimerCallBack(uint8timerId,uint8channel,uint8channelMode){if((timerId==OSAL_TIMER)&&(channelMode==HAL_TIMER_CH_MODE_OUTPUT_COMPARE)){osal_update_timers();}}//每一个时钟节拍跟新时钟结构体【OSAL_Timers.c】voidosal_update_timers(void){osalTimerUpdate(tmr_decr_time);}//【OSAL_Timers.c】staticvoidosalTimerUpdate(uint16updateTime){halIntState_tintSt
halIntState_tintState;
//【hal_mcu.h】其实就是一个无符号字符类型
//typedefunsignedcharhalIntState_t;
HAL_ENTER_CRITICAL_SECTION(intState);//维持全局中断状态
//【hal_mcu.h】
#defineHAL_ENTER_CRITICAL_SECTION(x)st(x=EA;
HAL_DISABLE_INTERRUPTS();)
//保存当前全局中断状态,然后关闭全局中断
#defineHAL_EXIT_CRITICAL_SECTION(x)st(EA=x;)
#defineHAL_CRITICAL_STATEMENT(x)st(halIntState_ts;HAL_ENTER_CRITICAL_SECTION(s);x;HAL_EXIT_CRITICAL_SECTION(s);)
tasksEvents【task_id】|=event_flag;//Stufftheeventbit(s)
//【sapi.c】
//uint16*tasksEvents;
HAL_EXIT_CRITICAL_SECTION(intState);//Releaseinterrupts
else
return(INVALID_TASK);//如果任务ID超出返回则返回任务无效
//返回值类型定义在【ZComDef.h】
//#defineINVALID_TASK1
return(ZSUCCESS);
};
//【OSAL_Tasks.h】
//事件处理函数原型:
typedefunsignedshort(*pTaskEventHandlerFn)(unsignedchartask_id,unsignedshortevent);//定义事件处理函数的函数指针类型
constpTaskEventHandlerFntasksArr【】={
macEventLoop,
nwk_event_loop,
Hal_ProcessEvent,
#ifdefined(MT_TASK)
MT_ProcessEvent,
#endif
APS_event_loop,
ZDApp_event_loop,
SAPI_ProcessEvent
//tasksArr中任务事件循环中的顺序必须和osalInitTask中任务的初始化顺序一致
constuint8tasksCnt=sizeof(tasksArr)/sizeof(tasksArr【0】);
//得到任务数
Else
//如果点亮时间百分比超过100%也就相当于常亮了,就执行LED常亮的设置
HalLedSet(leds,HAL_LED_MODE_ON);
//【hal_led.c】
//一样的前提是开始了LED硬件驱动服务
//检测要切换的LED模式
break;
//如果是闪烁模式,则将指定的LED闪烁一次,点亮时间默认为5%,闪烁周期是1S
caseHAL_LED_MODE_FLASH:
/*Defaultflash,Ntimes,D%dutycycle*/
HalLedBlink(leds,HAL_LED_DEFAULT_FLASH_COUNT,HAL_LED_DEFAULT_DUTY_CYCLE,HAL_LED_DEFAULT_FLASH_TIME);
//如果是连闪模式,则将指定的LED闪烁50次,点亮时间默认为5%,闪烁周期是1S
caseHAL_LED_MODE_ON:
caseHAL_LED_MODE_OFF:
caseHAL_LED_MODE_TOGGLE:
//如果是开、关、切换模式,则分别一个个的操作指定的LED
if(leds&led)
if(mode!
=HAL_LED_MODE_TOGGLE)
sts->mode=mode;/*ONorOFF*/
sts->mode^=HAL_LED_MODE_ON;/*Toggle*/
//开关的切换,利用了和1相异或为取反的特性。
到这里为止还只是设置了LED的
//模式,并没有真正的对LED进行开关的操作,也就是说LED并没有演示出效果。
HalLedOnOff(led,sts->mode);
//这个函数是对LED进行开关操作的真正的函数了,这个函数执行完后应该能看到
//LED状态的变化。
列举程序中部分段落(因为其他段落都差不多呵呵)【hal_led.c】
voidHalLedOnOff(uint8leds,uint8mode)
if(leds&HAL_LED_1)//检测是否是LED1
if(mode==HAL_LED_MODE_ON)//检测开关模式
HAL_TURN_ON_LED1();//点亮LED1
HAL_TURN_OFF_LED1();
…………
if(mode)
HalLedState|=leds;
HalLedState&=~leds;
//此用来记住当前操作的LED的状态,如果是点亮的就把HalLedState中相应的位置位,否则清零
leds^=led;
led<<=1;
default:
#elif(HAL_LED==TRUE)
LedOnOff(leds,mode);
#endif/*BLINK_LEDS&&HAL_LED*/
return(HalLedState);//返回的是操作了的LED的状态,每个LED在此状态中用1位来表示
}//通过上面程序的解读我发现,到目前为止对LED的操作真正实现的只有开、关、切换,
}//所谓的闪烁只是调用了一个系统事件设置函数
}//osal_set_event(Hal_TaskID,HAL_LED_BLINK_EVENT);难道这都是通过系统事件来
//实现的?
因为闪烁涉及到了时间占空比,估计还调用了定时器,那有可能还用到了中断,//嗯,有可能。
先接着分析下面的函数
//CheckforBrown-Outreset
ChkReset();//检测重启原因【OnBoard.c】
voidChkReset(void)
uint8rib;
//Isolateresetindicatorbits
rib=SLEEP&LRESET;//得到SLEEP中的RST状态【hal_mcu.h】
//#defineLRESET0x18
//#defineRESETPO0x00//上电重启
//#defineRESETEX0x08//外部重启
//#defineRESETWD0x10//看门狗重启
if(rib==RESETPO)//重启的原因【OnBoard.h】
//PutcodeheretohandlePower-Onreset
elseif(rib==RESETEX)
//PutcodeheretohandleExternalreset
elseif(rib==RESETWD)
//PutcodeheretohandleWatchDogreset
else//未知的重启原因,闪烁LED指示
HAL_DISABLE_INTERRUPTS();
led=HAL_LED_4;
while
(1)
HalLedSet(led,HAL_LED_MODE_ON);
MicroWait(62500);
HalLedSet(led,HAL_LED_MODE_OFF);
MicroWait(37500);
(led>>=1))
/*Timer2forOsaltimer*/
//设置OSAL的时钟
OnboardTimerIntEnable=FALSE;
HalTimerConfig(OSAL_TIMER,//8bittimer2
HAL_TIMER_MODE_CTC,//ClearTimeronCompare
HAL_TIMER_CHANNEL_SINGLE,//Channel1-default
HAL_TIMER_CH_MODE_OUTPUT_COMPARE,//OutputComparemode
OnboardTimerIntEnable,//Useinterrupt
Onboard_TimerCallBack);//ChannelMode
//【OnBoard.h】
//使用指定的定时器#defineOSAL_TIMERHAL_TIMER_2
//【hal_timer.h】
//#defineHAL_TIMER_00x00//8bittimer
//#defineHAL_TIMER_10x01//16bitMactimer
//#defineHAL_TIMER_20x02//8bittimer
//#defineHAL_TIMER_30x03//16bittimer
//#defineHAL_TIMER_MAX4//Maxnumberoftimer
//定时器的操作模式
//#defineHAL_TIMER_MODE_NORMAL0x01//NormalMode
//#defineHAL_TIMER_MODE_CTC0x02//ClearTimerOnCompare
//#defineHAL_TIMER_MODE_MASK(HAL_TIMER_MODE_NORMAL|HAL_TIMER_MODE_CTC)
//定时器通道定义
//#defineHAL_TIMER_CHANNEL_SINGLE0x01//SingleChannel-default
//#defineHAL_TIMER_CHANNEL_A0x02//ChannelA
//#defineHAL_TIMER_CHANNEL_B0x04//ChannelB
//#defineHAL_TIMER_CHANNEL_C0x08//ChannelC
//#defineHAL_TIMER_CHANNEL_MASK(HAL_TIMER_CHANNEL_SINGLE|\
HAL_TIMER_CHANNEL_A|\
HAL_TIMER_CHANNEL_B|\
HAL_TIMER_CHANNEL_C)
//通道模式
//#defineHAL_TIMER_CH_MODE_INPUT_CAPTURE0x01//ChannelModeInput-Capture
//#defineHAL_TIMER_CH_MODE_OUTPUT_COMPARE0x02//ChannelModeOutput_Compare
//#defineHAL_TIMER_CH_MODE_OVERFLOW0x04//ChannelModeOverflow
//#defineHAL_TIMER_CH_MODE_MASK(HAL_TIMER_CH_MODE_INPUT_CAPTURE|\
HAL_TIMER_CH_MODE_OUTPUT_COMPARE|\
HAL_TIMER_CH_MODE_OVERFLOW)
//更新定时器的函数【OnBoard.c】
voidOnboard_TimerCallBack(uint8timerId,uint8channel,uint8channelMode)
if((timerId==OSAL_TIMER)&&(channelMode==HAL_TIMER_CH_MODE_OUTPUT_COMPARE))
osal_update_timers();
//每一个时钟节拍跟新时钟结构体【OSAL_Timers.c】
voidosal_update_timers(void)
osalTimerUpdate(tmr_decr_time);
//【OSAL_Timers.c】
staticvoidosalTimerUpdate(uint16updateTime)
halIntState_tintSt
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2