電路如圖所示:

其中控制芯片使用SAM3S4B,通過SPI格式(單一的SAM3S4B為主端,AT86RE231為從端)與AT86RF231進行通訊,AT86RF231是一款工業(yè)級,低電壓供電,超低功耗,方便操作,遵循IEEE802.15.4-2006 硬件標準。AT86RF231將控制信號轉(zhuǎn)換為zigbee模式的差分對信號,通過2.45Ghz的諧波濾波器2450FB15L0001濾波后接入天線與其余zigbee端點進行通訊,2450FB15L0001主要是對接受到得zigbee信號進行濾波。
Zigbee框架下編譯程序,需要進行些簡單的設(shè)置,
因為處與zigbee協(xié)議?蚣苤校糠衷创a被atmel,封裝起來,在man函數(shù)中,SYS_sysinit();系統(tǒng)初始化給出.h文件,而沒有具體的C代碼。這意味ZIGBEE的具體結(jié)構(gòu)核心部分不是開源的。實際中SYS_sysinit()在libBc_All_At91sam3s4c_Rf231_Iar.a中,該文件被封裝起來。
其中,對bitcloud編譯生成的是libHAL_Sam3sEkRf2xx_At91sam3s4c_64Mhz_Iar.a。
這里面即便被封住,我們可以進入bitcloud源碼內(nèi),解讀代碼,如WTD操作,HAL_InstallInterruptVector(),TimeTick_Configure()還是可以進行代碼解讀的。那對zigbee格式下的函數(shù)應(yīng)該怎樣跟蹤解析代碼:例如pio.h中,PIO_Configure();無法看到C代碼的實現(xiàn)過程?梢允髽擞覔魀io.h文件(見下圖1),open containing folder,打開文件夾,找到include中的pio.h文件,可以推測出點C文件如果有,應(yīng)該存在于source中。進行代碼解讀。

圖1
在下面歷程中,給出協(xié)調(diào)器和節(jié)點的實現(xiàn)。
協(xié)調(diào)器部分程序:
int main(void)
{
//初始化,相關(guān)系統(tǒng)配置
SYS_SysInit();
..
..
for(;;)
{
//數(shù)據(jù)處理
..
..
SYS_RunTask();
}
}
SYS_SysInit();函數(shù)是系統(tǒng)的函數(shù),用來初始化系統(tǒng)的硬件;
SYS_RunTask();是調(diào)用zigbee的入口函數(shù),會調(diào)用BitCloud協(xié)議棧中的用戶應(yīng)用程序,即APL_TaskHandler();
voidAPL_TaskHandler(void)
{
switch (appState)
{
case APP_INITIAL_STATE:
initHardware();
initNetwork();
break;
case APP_JOINING_STATE:
startNetwork();
break;
case APP_JOINED_STATE:
break;
default:
break;
}
}
APL_TaskHandler();這個函數(shù)類似個有限狀態(tài)機,是zigbee所處狀態(tài)的處理,程序在初始化時static AppState_tappState = APP_INITIAL_STATE;
如果沒有添加入網(wǎng)絡(luò),或者從網(wǎng)絡(luò)中斷掉,在主程序每次循環(huán)的時候,會添加入網(wǎng)絡(luò),如果是已將處于zigbee網(wǎng)絡(luò)中,則處于APP_JOINED_STATE狀態(tài),直接退出APL_TaskHandler()函數(shù)。
我們可以看下具體狀態(tài)下的子函數(shù);
硬件初始化只是配置個LED,當zigbee網(wǎng)絡(luò)正常工作時,led1常亮狀態(tài),否認閃亮。
static void initHardware(void)
{
LED_Configure(APP_LED_0);
LED_Configure(APP_LED_1);
}
而對協(xié)調(diào)器的配置是zigbee配置的關(guān)鍵部分,下面一段代碼將本身配置為協(xié)調(diào)器,并在網(wǎng)絡(luò)中定義兩個節(jié)點。
static void initNetwork(void)
{
DeviceType_tdeviceType = DEVICE_TYPE_COORDINATOR; //配置成協(xié)調(diào)器
CS_WriteParameter(CS_DEVICE_TYPE_ID, &deviceType);
boolpredefPANID = true;
uint16_tnwkPANID = 0x1000;
CS_WriteParameter(CS_NWK_PREDEFINED_PANID_ID, &predefPANID);
CS_WriteParameter(CS_NWK_PANID_ID, &nwkPANID);//add by jacky
// 定義數(shù)據(jù)節(jié)點0
apsDataReq.dstAddrMode = APS_SHORT_ADDRESS;
apsDataReq.dstAddress.shortAddress = 0;
apsDataReq.profileId = APP_PROFILE_ID;
apsDataReq.dstEndpoint = APP_DATA_ENDPOINT;//0X20
apsDataReq.clusterId = APP_CLUSTER_ID;
apsDataReq.srcEndpoint = APP_DATA_ENDPOINT;//0X20
apsDataReq.asdu = (uint8_t *)sensor_buf;
apsDataReq.asduLength = sizeof(execute_buf);//傳輸數(shù)據(jù)
apsDataReq.txOptions.acknowledgedTransmission = 0;
apsDataReq.radius = 0;
apsDataReq.APS_DataConf = apsDataReqConf;
// 定義數(shù)據(jù)節(jié)點1
apsDataReq1.dstAddrMode = APS_SHORT_ADDRESS;
apsDataReq1.dstAddress.shortAddress = 0;
apsDataReq1.profileId = APP_PROFILE_ID;
apsDataReq1.dstEndpoint = 0x40;
apsDataReq1.clusterId = APP_CLUSTER_ID;
apsDataReq1.srcEndpoint = 0x40;
apsDataReq1.asdu = (uint8_t *)execute_buf;
apsDataReq1.asduLength = sizeof(execute_buf);//傳輸數(shù)據(jù)
apsDataReq1.txOptions.acknowledgedTransmission = 0;
apsDataReq1.radius = 0;
apsDataReq1.APS_DataConf = apsDataReqConf1;
appState = APP_JOINING_STATE;
SYS_PostTask(APL_TASK_ID);
}
初始化結(jié)束后會改變appState的狀態(tài),appState = APP_JOINING_STATE; 進行網(wǎng)絡(luò)的加入操作,使用SYS_PostTask(APL_TASK_ID);來投遞任務(wù),讓系統(tǒng)再次調(diào)用APL_TaskHandler() 去執(zhí)行case APP_JOINING_STATE進而去執(zhí)行startNetwork()函數(shù)。
startNetwork()創(chuàng)建一個定時器用來控制led的亮滅來表示網(wǎng)絡(luò)的連接狀態(tài),在注冊一個網(wǎng)絡(luò)連接確認的回調(diào)函數(shù)。
static void startNetwork(void)
{
blinkTimer.interval = BLINK_TIMER_INTERVAL;
blinkTimer.mode = TIMER_REPEAT_MODE;
blinkTimer.callback = blinkTimerFired;
HAL_StartAppTimer(&blinkTimer);
startNetworkReq.ZDO_StartNetworkConf = ZDO_StartNetworkConf;//回調(diào)函數(shù)
ZDO_StartNetworkReq(&startNetworkReq);
}
回調(diào)函數(shù)中,主要是判斷zigbee網(wǎng)絡(luò)連接,連接成功,關(guān)閉定時器和注冊網(wǎng)絡(luò)節(jié)點。
static void ZDO_StartNetworkConf(ZDO_StartNetworkConf_t* conf)
{
HAL_StopAppTimer(&blinkTimer); //add by lht
if (ZDO_SUCCESS_STATUS == conf->status)
{
appState = APP_JOINED_STATE;
// 注冊網(wǎng)絡(luò)節(jié)點0
registerDataEndpointReq.simpleDescriptor = &dataEndpoint;
registerDataEndpointReq.APS_DataInd = APS_DataIndData;
APS_RegisterEndpointReq(®isterDataEndpointReq);
// 注冊網(wǎng)絡(luò)節(jié)點1
registerDataEndpointReq1.simpleDescriptor = &dataEndpoint1;
registerDataEndpointReq1.APS_DataInd = APS_DataIndData1;
APS_RegisterEndpointReq(®isterDataEndpointReq1);
}
else
{
appState = APP_JOINING_STATE;
}
SYS_PostTask(APL_TASK_ID);
}
zigbee數(shù)據(jù)發(fā)送函數(shù):
static void sendDataBlock(unsigned char channel)
{
switch(channel)
{
case Sensor:
APS_DataReq(&apsDataReq);
break;
case Execute:
APS_DataReq(&apsDataReq1);
break;
default:
break;
}
}
zigbee數(shù)據(jù)接受函數(shù):
static void APS_DataIndData(APS_DataInd_t *ind) //data come from sensor module
{
zigbee_in_flag = 1;
memcpy(&sensor_data[1],ind->asdu, 18);
sensor_from_address = ind->srcAddress.shortAddress;
}
static void APS_DataIndData1(APS_DataInd_t *ind) //data come from excute module
{
memcpy(init_data,ind->asdu, 30);
to_excute_address = ind->srcAddress.shortAddress;
if(init_data[0] == 0xaa)
{
enable_count = 1;
excute_open = 1;
}
}
在zigbee的節(jié)點函數(shù)APL_TaskHandler(),與協(xié)調(diào)器程序中多的狀態(tài)是:離開zigbee網(wǎng)絡(luò),定義的宏是APP_LEAVE_STATE。
voidAPL_TaskHandler(void)
{
switch (appState)
{
case APP_INITIAL_STATE:
&nbnbsp; initHardware();
initNetwork();
break;
case APP_JOINING_STATE:
startNetwork();
break;
case APP_JOINED_STATE:
break;
case APP_LEAVE_STATE:
&nbsnbsp; leaveNetwork();
break;
case APP_LEAVING_STATE:
break;
default:
break;
}
}