Zigbee 兩串列埠除錯助手通過兩節點無線通訊
阿新 • • 發佈:2019-01-08
Zigbee 兩串列埠除錯助手通過兩節點無線通訊
//Coordinator.c #include "OSAL.h" #include "AF.h" #include "ZDApp.h" #include "ZDObject.h" #include "ZDProfile.h" #include <string.h> #include "Coordinator.h" #include "DebugTrace.h" #if !defined(WIN32) //???? #include "OnBoard.h" #endif #include "hal_lcd.h" #include "hal_led.h" #include "hal_key.h" #include "hal_uart.h" const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS]= { GENERICAPP_CLUSTERID }; //簡單裝置描述符(描述一個ZigBee裝置節點) const SimpleDescriptionFormat_t GenericApp_SimpleDesc= { GENERICAPP_ENDPOINT, GENERICAPP_PROFID, GENERICAPP_DEVICEID, GENERICAPP_DEVICE_VERSION, GENERICAPP_FLAGS, GENERICAPP_MAX_CLUSTERS, (cId_t*)GenericApp_ClusterList, //????? 0, (cId_t *)NULL }; endPointDesc_t GenericApp_epDesc;//節點描述符 byte GenericApp_TaskID;//任務優先順序 byte GenericApp_TransID;//資料傳送序列號。 void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pckt);//訊息處理函式 void GenericApp_SendTheMessage(void);//資料傳送函式 void GenericApp_SendTheMessage_two(void); static void rxCB(uint8 port,uint8 envent);//??????????? void GenericApp_Init(byte task_id)//任務初始化函式 { GenericApp_TaskID =task_id; //初始化任務優先順序(任務優先順序有協議棧的作業系統OSAL分配) GenericApp_TransID =0; //傳送資料包的序號初始化為0 //對節點描述符進行初始化 GenericApp_epDesc.endPoint =GENERICAPP_ENDPOINT; GenericApp_epDesc.task_id =&GenericApp_TaskID; GenericApp_epDesc.simpleDesc =(SimpleDescriptionFormat_t*)&GenericApp_SimpleDesc; GenericApp_epDesc.latencyReq =noLatencyReqs; afRegister(&GenericApp_epDesc);//afRegister()對節點的描述符進行註冊。註冊後,才能使用OSAL提供的系統服務。 halUARTCfg_t uartConfig;//該結構體變數是實現 串列埠的配置 //串列埠的初始化 uartConfig.configured =TRUE; uartConfig.baudRate =HAL_UART_BR_115200;//波特率 uartConfig.flowControl =FALSE; //流控制 uartConfig.callBackFunc =rxCB; //填的是回撥函式 ,數的指標(即函式的地址)作為引數傳遞給另一個函式, //其實callBackFunc是一個函式指標,它的定義為halUARTCBack_t callBackFunc; //而halUARTCBack_t的定義為 typed void (*halUARTCBack_t)(uint8 port,uint8 envent) 定義的是一個函式指標 HalUARTOpen(0,&uartConfig); //串列埠是否開啟 } //下面這個是回撥函式,回電函式就是一個通過函式指標(函式地址)呼叫的函式,如果把函式的指標(即函式的地址)作為引數傳遞給另一 //個函式,當通過該指正呼叫它鎖指向的函式時,稱為函式的回撥。 //回撥函式不是有該函式的實現方直接呼叫的,而是在特定的事件或條件時,由另一方呼叫的額,用於對該事件或條件進行響應。 //回撥函式機制提供了系統對非同步事件的處理能力。 unsigned char uartbuf[128];//串列埠接收發送資料緩衝單元 static void rxCB(uint8 port,uint8 envent) { int rxlen=Hal_UART_RxBufLen(0); //接收緩衝區資料長度,位元組為單位 if(rxlen) { HalUARTRead(0,uartbuf,rxlen); //從串列埠讀取資料放在uartbuf緩衝區中 // HalUARTWrite(0,uartbuf,rxlen); uartbuf[rxlen]='\0'; GenericApp_SendTheMessage_two() ; // HalLedBlink(HAL_LED_2,0,50,500); //LED2 閃爍 } } //訊息處理函式 UINT16 GenericApp_ProcessEvent(byte task_id,UINT16 events) { afIncomingMSGPacket_t* MSGpkt;//MSGpkt用於指向接收訊息結構體的指標 if(events&SYS_EVENT_MSG) { MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID);//osal_msg_receive()從訊息佇列上接收訊息 while(MSGpkt) { switch(MSGpkt->hdr.event) { case AF_INCOMING_MSG_CMD: //接受到新資料的訊息的ID是AF_INCOMING_MSG_CMD,這個巨集是在協議棧中定義好的值為0x1A //接受到的是無線資料包 GenericApp_MessageMSGCB(MSGpkt);//功能是完成對接受資料的處理 break; default: break; } osal_msg_deallocate((uint8 *)MSGpkt);//接收到的訊息處理完後,釋放訊息所佔的儲存空間 MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID); //處理完一個訊息後,再從訊息佇列裡接受訊息,然後對其進行相應處理,直到所有訊息處理完 } return (events ^ SYS_EVENT_MSG); } return 0; } bool flag=true; uint16 shorAddr=0; void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pkt) { unsigned char addr[2]; switch(pkt->clusterId) { case GENERICAPP_CLUSTERID: if(flag) { osal_memcpy(addr,pkt->cmd.Data,2); osal_memcpy(&shorAddr,addr,2); flag=false; } else { HalUARTWrite( 0, pkt->cmd.Data, (pkt->cmd.DataLength) ) ; //接收的資料傳送的串列埠 HalLedBlink(HAL_LED_2,0,50,500); //LED2 閃爍 } break; } } void GenericApp_SendTheMessage_two(void) { afAddrType_t my_DstAddr; my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;//資料傳送模式:可選 單播、廣播、多播方式 這裡選Addr16Bit表單播 my_DstAddr.endPoint=GENERICAPP_ENDPOINT; //初始化埠函 my_DstAddr.addr.shortAddr=shorAddr; //標誌目的地址節點的網路地址 這裡是協調器的地址 //下面是資料傳送 長度 資料傳送緩衝區 AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,\ osal_strlen(uartbuf)+1,uartbuf,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS); HalLedBlink(HAL_LED_1,0,50,500); //LED2 閃爍 }
//Enddevice.c //新增串列埠接收回調函式,然後傳送到天線 #include "OSAL.h" #include "AF.h" #include "ZDApp.h" #include "ZDObject.h" #include "ZDProfile.h" #include <string.h> #include "Coordinator.h" #include "DebugTrace.h" #if !defined(WIN32) #include "OnBoard.h" #endif #include "hal_lcd.h" #include "hal_led.h" #include "hal_key.h" #include "hal_uart.h" #define SEND_DATA_EVENT 0x01 //傳送事件id const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS]= { GENERICAPP_CLUSTERID }; //初始化埠描述符 const SimpleDescriptionFormat_t GenericApp_SimpleDesc= { GENERICAPP_ENDPOINT, GENERICAPP_PROFID, GENERICAPP_DEVICEID, GENERICAPP_DEVICE_VERSION, GENERICAPP_FLAGS, 0, (cId_t*)NULL, GENERICAPP_MAX_CLUSTERS, (cId_t*)GenericApp_ClusterList }; endPointDesc_t GenericApp_epDesc;//節點描述符 byte GenericApp_TaskID; //任務優先順序 byte GenericApp_TransID; //資料傳送序列號 devStates_t GenericApp_NwkState;//儲存節點狀態 void GenericApp_MessageMSGCB(afIncomingMSGPacket_t* pckt);//訊息處理函式的宣告 void GenericApp_SendTheMessage(void); //資料傳送函式的宣告 void GenericApp_SendTheMessage_two(void); //資料傳送函式的宣告 static void rxCB(uint8 port,uint8 envent);//??????????? void To_string(uint8 *dest,char *src,uint8 length); //任務初始化函式 void GenericApp_Init(byte task_id) { GenericApp_TaskID = task_id;//初始化任務優先順序 GenericApp_NwkState =DEV_INIT; //初始化為DEV_INIT,表節點沒有連線到ZigBee網路 GenericApp_TransID =0; //傳送資料包的序列號初始化為0 //對節點描述符進行初始化 GenericApp_epDesc.endPoint=GENERICAPP_ENDPOINT; GenericApp_epDesc.task_id =&GenericApp_TaskID; GenericApp_epDesc.simpleDesc=(SimpleDescriptionFormat_t*)&GenericApp_SimpleDesc; GenericApp_epDesc.latencyReq=noLatencyReqs; //afRegister()函式將節點描述符進行註冊,註冊後才可以使用OSAL提供的系統服務 afRegister(&GenericApp_epDesc); halUARTCfg_t uartConfig;//該結構體變數是實現 串列埠的配置 //串列埠的初始化 uartConfig.configured =TRUE; uartConfig.baudRate =HAL_UART_BR_115200;//波特率 uartConfig.flowControl =FALSE; //流控制 uartConfig.callBackFunc =rxCB; //填的是回撥函式 ,數的指標(即函式的地址)作為引數傳遞給另一個函式, //其實callBackFunc是一個函式指標,它的定義為halUARTCBack_t callBackFunc; //而halUARTCBack_t的定義為 typed void (*halUARTCBack_t)(uint8 port,uint8 envent) 定義的是一個函式指標 HalUARTOpen(0,&uartConfig); //串列埠是否開啟 } //unsigned char theMessageData[128]="EndDevice";//存放傳送資料 //回撥函式不是有該函式的實現方直接呼叫的,而是在特定的事件或條件時,由另一方呼叫的額,用於對該事件或條件進行響應。 //回撥函式機制提供了系統對非同步事件的處理能力。 unsigned char uartbuf[128];//串列埠接收發送資料緩衝單元 static void rxCB(uint8 port,uint8 envent) { int rxlen=Hal_UART_RxBufLen(0); //接收緩衝區資料長度,位元組為單位 if(rxlen) { HalUARTRead(0,uartbuf,rxlen); //從串列埠讀取資料放在uartbuf緩衝區中 // HalUARTWrite(0,uartbuf,rxlen); //傳送到天 uartbuf[rxlen]='\0'; GenericApp_SendTheMessage_two() ; // HalLedBlink(HAL_LED_2,0,50,500); //LED2 閃爍 } } //訊息處理函式 UINT16 GenericApp_ProcessEvent(byte task_id,UINT16 events) { afIncomingMSGPacket_t* MSGpkt; if(events&SYS_EVENT_MSG) { MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID); while(MSGpkt) { switch(MSGpkt->hdr.event) { case ZDO_STATE_CHANGE: GenericApp_NwkState=(devStates_t)(MSGpkt->hdr.status);//讀取節點的裝置型別 if(GenericApp_NwkState==DEV_END_DEVICE) { //當中斷節點加入網路後使用osal_set_envent()函式設定SEND_DATA_EVENT事件,當事件發生時,執行事件處理函式 // osal_set_event(GenericApp_TaskID,SEND_DATA_EVENT);//?????????????????????????? GenericApp_SendTheMessage(); //終端節點型別,執行無線資料傳送 } break; case AF_INCOMING_MSG_CMD: //接受到新資料的訊息的ID是AF_INCOMING_MSG_CMD,這個巨集是在協議棧中定義好的值為0x1A //接受到的是無線資料包 GenericApp_MessageMSGCB(MSGpkt);//功能是完成對接受資料的處理 break; default: break; } osal_msg_deallocate((uint8*)MSGpkt); MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID); } return (events^SYS_EVENT_MSG); } if(events&SEND_DATA_EVENT)//這個函式為什麼放在這裡,好好想想才行???? { GenericApp_SendTheMessage(); osal_start_timerEx(GenericApp_TaskID,SEND_DATA_EVENT,1000); //定時器,三個引數:一參:表定時事件到底後,那個任務對其作出響應 //二參:時間ID,表時間達到後,事件發生,該事件的處理函式中實現資料的傳送。 //三參:定時的時間數量,單位毫秒。 osal_stop_timerEx(GenericApp_TaskID,SEND_DATA_EVENT); return (events^SEND_DATA_EVENT);//清除事件標誌 } return 0; } uint16 shorAddr; unsigned char addr[2]; void GenericApp_SendTheMessage(void) { shorAddr=NLME_GetShortAddr(); afAddrType_t my_DstAddr; my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;//資料傳送模式:可選 單播、廣播、多播方式 這裡選Addr16Bit表單播 my_DstAddr.endPoint=GENERICAPP_ENDPOINT; //初始化埠函 my_DstAddr.addr.shortAddr=0x0000; //標誌目的地址節點的網路地址 這裡是協調器的地址 //下面是資料傳送 長度 資料傳送緩衝區 AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,\ 2, (uint8*)&shorAddr,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS); } void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pkt) { switch(pkt->clusterId) { case GENERICAPP_CLUSTERID: HalUARTWrite( 0, pkt->cmd.Data, (pkt->cmd.DataLength) ) ; //接收的資料傳送的串列埠 HalLedBlink(HAL_LED_2,0,50,500); //LED2 閃爍 // GenericApp_SendTheMessage_two() ; break; } } void GenericApp_SendTheMessage_two(void) { afAddrType_t my_DstAddr; my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;//資料傳送模式:可選 單播、廣播、多播方式 這裡選Addr16Bit表單播 my_DstAddr.endPoint=GENERICAPP_ENDPOINT; //初始化埠函 my_DstAddr.addr.shortAddr=0x0000; //標誌目的地址節點的網路地址 這裡是協調器的地址 //下面是資料傳送 長度 資料傳送緩衝區 AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,\ osal_strlen(uartbuf)+1,uartbuf,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS); HalLedBlink(HAL_LED_1,0,50,500); //LED2 閃爍 // HalUARTWrite(0, addr,2); }