Zigbee协议栈————广播组网
目錄
1.基礎(chǔ)概念
2.Zigbee協(xié)議棧工作流程
3。代碼講解
1.基礎(chǔ)概念
在Zigbee網(wǎng)絡(luò)中存在3中邏輯設(shè)備:協(xié)調(diào)器、路由器、終端。
(這個實驗當(dāng)中我們只用到協(xié)調(diào)器以及終端)。
協(xié)調(diào)器:協(xié)調(diào)器負(fù)責(zé)啟動網(wǎng)絡(luò),當(dāng)啟動和配置好網(wǎng)絡(luò)后,協(xié)調(diào)器就會像一個路由器一樣或者就消失了。
終端:網(wǎng)絡(luò)中的一個設(shè)備,一個節(jié)點。
?廣播:當(dāng)應(yīng)用程序需要將數(shù)據(jù)包發(fā)送給網(wǎng)絡(luò)的每一個設(shè)備時,使用這種模式。地址模式設(shè)置為
AddrBroadcast。目標(biāo)地址可以設(shè)置為下面廣播地址的一種:
NWK BROADCAST SHORTADDR DEVALL(0xFFFF)--數(shù)據(jù)包將被傳送到網(wǎng)絡(luò)上的所有設(shè)備,包括睡眠中的設(shè)備。
NWK BROADCAST SHORTADDR DEVRXON(0xFFFD)-數(shù)據(jù)包將被傳送到網(wǎng)絡(luò)上除了睡眠中的所有設(shè)備。
NWK BROADCAST SHORTADDR DEVZCZR(0xFFFC)--數(shù)據(jù)包發(fā)送給所有的路由器,包括協(xié)調(diào)器。
2.Zigbee協(xié)議棧工作流程
在main()函數(shù)中初始化操作系統(tǒng)osal_init_system(),初始化一些外設(shè)(協(xié)議棧已經(jīng)將這些外設(shè)封裝好了,可以像32一樣調(diào)用函數(shù)使用。),最后進(jìn)入osal_start_system()中執(zhí)行操作系統(tǒng),并且程序會一直處于這個函數(shù)當(dāng)中,不會返回(函數(shù)中有死循環(huán)),在這個函數(shù)當(dāng)中判斷是否有事件發(fā)生,然后會根據(jù)優(yōu)先級來處理這些事件(任務(wù))。我們以后主要需要修改在SampleApp_Init()當(dāng)中.
?3.代碼講解
協(xié)議棧中很多東西已經(jīng)幫我們寫好,我們以后使用僅僅需要修改增加一些內(nèi)容。因此代碼不需要全部都懂。(初學(xué)者不要嘗試將所有的代碼都看懂,循序漸進(jìn)。)
在目錄中找到SampleApp.c,打開它,并在該C文件的頂部包含#include"MT_UART.h"
#include "MT_APP.h"
#include "MT.h"
#include "string.h"
這四個頭文件。接下來找到void SampleApp_Init( uint8 task_id )這個函數(shù)
void SampleApp_Init( uint8 task_id ) { SampleApp_TaskID = task_id;SampleApp_NwkState = DEV_INIT;SampleApp_TransID = 0;//這一部分為新加進(jìn)來的代碼//------------------------配置串口---------------------------------MT_UartInit(); //串口初始化MT_UartRegisterTaskID(task_id); //注冊串口任務(wù)HalUARTWrite(0,"UartInit OK\n", sizeof("UartInit OK\n"));//-----------------------------------------------------------------#if defined ( BUILD_ALL_DEVICES )if ( readCoordinatorJumper() )zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;elsezgDeviceLogicalType = ZG_DEVICETYPE_ROUTER; #endif // BUILD_ALL_DEVICES#if defined ( HOLD_AUTO_START )ZDOInitDevice(0); #endifSampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;//廣播模式SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;//廣播地址 /*//組播的代碼// Setup for the flash command's destination address - Group 1SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;*/SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT;SampleApp_epDesc.task_id = &SampleApp_TaskID;SampleApp_epDesc.simpleDesc= (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;SampleApp_epDesc.latencyReq = noLatencyReqs;afRegister( &SampleApp_epDesc );RegisterForKeys( SampleApp_TaskID ); /*//組播的代碼// By default, all devices start out in Group 1SampleApp_Group.ID = 0x0001;osal_memcpy( SampleApp_Group.name, "Group 1", 7 );aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); */#if defined ( LCD_SUPPORTED )HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); #endif }?其中?MT_UartInit()在目錄中MT文件中的MT_UART.c的文件當(dāng)中,為串口的初始化。
?
?這個初始化的函數(shù)當(dāng)中,我們需要將波特率設(shè)置好,流控制關(guān)閉,其他的可以不用管。
? ? ? ? 然后我們就可以調(diào)用HalUARTWrite(0,"UartInit OK\n", sizeof("UartInit OK\n"))來發(fā)送初始化完成的提示。然后,如上面的代碼塊一樣,將組播的代碼注釋掉。
? ? ? ? 接下來,我們進(jìn)入到uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )當(dāng)中。
//在這個函數(shù)當(dāng)中完成對事件的處理 uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) {afIncomingMSGPacket_t *MSGpkt;(void)task_id; if ( events & SYS_EVENT_MSG ){MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );while ( MSGpkt ){switch ( MSGpkt->hdr.event ){case KEY_CHANGE:SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );break;case AF_INCOMING_MSG_CMD://接收到數(shù)據(jù)包就進(jìn)行處理SampleApp_MessageMSGCB( MSGpkt );break;case ZDO_STATE_CHANGE://協(xié)調(diào)器狀態(tài)改變就進(jìn)入下面的函數(shù),協(xié)調(diào)器剛建立網(wǎng)絡(luò)就會進(jìn)去SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);if ( (SampleApp_NwkState == DEV_ZB_COORD)|| (SampleApp_NwkState == DEV_ROUTER)|| (SampleApp_NwkState == DEV_END_DEVICE) ){osal_start_timerEx( SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT,SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );}else{}break;default:break;}osal_msg_deallocate( (uint8 *)MSGpkt );MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );}return (events ^ SYS_EVENT_MSG);}if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )//上面有出現(xiàn)哦,協(xié)調(diào)器狀態(tài)改變{SampleApp_SendPeriodicMessage();//協(xié)調(diào)器發(fā)送數(shù)據(jù) osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,(SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);}return 0; }接下來進(jìn)入SampleApp_SendPeriodicMessage()函數(shù)當(dāng)中。
void SampleApp_SendPeriodicMessage( void ) {//聯(lián)網(wǎng)后進(jìn)入這個函數(shù)uint8 *buff=NULL;if(zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR)//判斷Zigbee的邏輯類型,如果是協(xié)調(diào)器{buff="I am coordinator device\r\n";}else if(zgDeviceLogicalType == ZG_DEVICETYPE_ENDDEVICE)//如果是終端{(lán)buff="I am endpoint device\r\n";}// AF_DataRequest()這個函數(shù)是真正發(fā)送數(shù)據(jù)的函數(shù),我們需要將第三第四個參數(shù)該為數(shù)組的大小,以及數(shù)組的內(nèi)容,然后就可以發(fā)送了。if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,SAMPLEAPP_PERIODIC_CLUSTERID,strlen(buff),//傳輸數(shù)據(jù)的字節(jié)大小buff,//傳輸數(shù)據(jù)&SampleApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ){}else{} }?數(shù)據(jù)發(fā)送完了,當(dāng)接受到數(shù)據(jù)包后,MSGpkt->hdr.event=AF_INCOMING_MSG_CMD,接下來,我們就要進(jìn)入SampleApp_MessageMSGCB( MSGpkt )當(dāng)中。
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )//無線數(shù)據(jù)包接收到之后 {uint16 flashTime;switch ( pkt->clusterId ){case SAMPLEAPP_PERIODIC_CLUSTERID://接收到該命令后執(zhí)行的代碼HalUARTWrite(0,(pkt->cmd).Data,(pkt->cmd).DataLength);//將接受到的數(shù)據(jù)打印到串口中break;case SAMPLEAPP_FLASH_CLUSTERID:flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );break;} }至此,代碼就完成了。接下來就可以燒錄,看現(xiàn)象了。
4.可能遇到的問題
?1.注意協(xié)調(diào)器與終端的燒錄,需要分開燒錄。可由上圖所示更改。
2.以下問題為版本不兼容
以及一堆 Undefined external "?V1" referred in AF類似的,都是由于版本不兼容的原因。解決方法:
?
?將16改為8
?在?ZStack-CC2530-2.5.1a\Projects\zstack\ZMain\TI2530DB下的chipcon_cstartup.s51文件中刪除END,并添加以下代碼:
;----------------------------------------------------------------; ; Virtual registers ; ; ================= ; ; Below is some segment needed for the IAR ICC C/EC++ compiler ; ; ; ; BREG : A segment for 8 bit registers for use by the compiler. ; ; ?B0 is the first register. ; ; VREG : Segment that holds up to 32 virtual registers for ; ; use by the compiler. ?V0 is the first register. ; ; PSP : Segment containing the PDATA stack pointer (?PSP) ; ; XSP : Segment containing the XDATA stack pointer (?XSP) ; ; ; ;----------------------------------------------------------------; ;----------------------------------------------------------------;PROGRAM VIRTUAL_REGISTERSPUBLIC ?B0PUBLIC ?V0PUBLIC ?V1PUBLIC ?V2PUBLIC ?V3PUBLIC ?V4PUBLIC ?V5PUBLIC ?V6PUBLIC ?V7PUBLIC ?V8PUBLIC ?V9PUBLIC ?V10PUBLIC ?V11PUBLIC ?V12PUBLIC ?V13PUBLIC ?V14PUBLIC ?V15PUBLIC ?V16PUBLIC ?V17PUBLIC ?V18PUBLIC ?V19PUBLIC ?V20PUBLIC ?V21PUBLIC ?V22PUBLIC ?V23PUBLIC ?V24PUBLIC ?V25PUBLIC ?V26PUBLIC ?V27PUBLIC ?V28PUBLIC ?V29PUBLIC ?V30PUBLIC ?V31PUBLIC ?PSPPUBLIC ?XSPRSEG BREG:BIT:NOROOT ?B0:DS 8RSEG VREG:DATA:NOROOT ?V0:DS 1 ?V1:DS 1 ?V2:DS 1 ?V3:DS 1 ?V4:DS 1 ?V5:DS 1 ?V6:DS 1 ?V7:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V7 ?V8:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V8 ?V9:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V9 ?V10:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V10 ?V11:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V11 ?V12:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V12 ?V13:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V13 ?V14:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V14 ?V15:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V15 ?V16:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V16 ?V17:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V17 ?V18:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V18 ?V19:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V19 ?V20:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V20 ?V21:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V21 ?V22:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V22 ?V23:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V23 ?V24:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V24 ?V25:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V25 ?V26:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V26 ?V27:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V27 ?V28:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V28 ?V29:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V29 ?V30:DS 1RSEG VREG:DATA:NOROOTREQUIRE ?V30 ?V31:DS 1RSEG PSP:DATA:NOROOTEXTERN ?RESET_PSPREQUIRE ?RESET_PSP ?PSP:DS 1RSEG XSP:DATA:NOROOTEXTERN ?RESET_XSPREQUIRE ?RESET_XSP ?XSP:DS 2ENDMOD ; VIRTUAL_REGISTERSEND3.注意在燒錄前需要預(yù)編譯
?
只有ZTOOL_P1前沒有x,其它的都需要在前面加一個x。
4.注意協(xié)議棧里的串口0,使用的是P0_2(RX),P0_3(TX)。
總結(jié)
以上是生活随笔為你收集整理的Zigbee协议栈————广播组网的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 费曼先生 找数学家“麻烦”
- 下一篇: UBLOX配置/GPS配置设置/u-ce