ZigBee单播通信原理、串口配置 (对于理解收发数据的过程非常重要)

来源:互联网 发布:flash cs5 mac中文版 编辑:程序博客网 时间:2024/06/12 18:50

ZigBee网络通信学习方法:
1,刚开始,我们确实需要借助官方模板,添加简单的代码实验,建立感性的认识
2,然后在官方代码基本实验基础上,了解相关概念,掌握通信过程原理,结合自己的理解,自己动手做一个个性化的实验
   ,来验证自己的理解。
  
ZigBee通信方式:单播、广播、组播、绑定。


先看一下单播:
单播:在ZigBee网络里面,模块之间要进行通信,发送模块非常明确知道接收模块的网络地址,以这个地址发送数据给接收模块,叫单播。
  
 
ZigBee模块地址特点:
   模块在入网的时候,父节点随机分配地址给子节点。但是协调器模块在网络里面的地址永远是0x00!!!
   
   

发送模块:

#define SAMPLEAPP_ENDPOINT           20  //定义端点编号afAddrType_t     SampleApp_Periodic_DstAddr; //声明SampleApp_P2P_DstAddr.addrMode            = (afAddrMode_t)Addr16Bit; //声明为点播 SampleApp_P2P_DstAddr.endPoint            = SAMPLEAPP_ENDPOINT; //接收模块的端点SampleApp_P2P_DstAddr.addr.shortAddr      = 0x0000;            //发给协调器,即协调器地址,协调器网络地址始终为0x0000endPointDesc_t SampleApp_epDesc;SampleApp_epDesc.endPoint   = SAMPLEAPP_ENDPOINT;//模块的端点SampleApp_epDesc.task_id    = &SampleApp_TaskID;//指明数据由接收方的哪一个任务来处理(与应用层的任务绑定)SampleApp_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;//更加详细的描述商战的情况,就像描述一个房间里面有多少人一样SampleApp_epDesc.latencyReq = noLatencyReqs;uint8 SampleApp_TransID = 0;afRegister( &SampleApp_epDesc );//端点必须要到系统里面注册绑定 uint8 SendBuf[] = "hello world!"; AF_DataRequest( &SampleApp_P2P_DstAddr,//接收模块                 &SampleApp_epDesc,                SAMPLEAPP_P2P_CLUSTERID,//指明接收模块的簇,相当于指明了数据要发到房间里面的具体的哪一个人 #define SAMPLEAPP_P2P_CLUSTERID 4                (uint8)osal_strlen(SendBuf)+1,//发送的字节大小                SendBuf,//发送数组的首地址                &SampleApp_TransID,//表示已经成功发送了多少帧,这里要传地址,底层发送成功以后,会修改这个值                AF_DISCV_ROUTE,                AF_DEFAULT_RADIUS);/* 表示SendBuf数据从发送方的20号端口出去,发到协调器的20号端口,并且由协调器的SampleApp_TaskID任务来处理接收到的消息,且以单播的形式发送数据*/



AF_DataRequest把SendBuf中的前10个字节发送给协调器(协调器的地址一定为0x0000)。     
   
   
接收模块:

在事件处理函数:

void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ){  //把收到的数据打印到串口  {    // uint8 afRxData[30]={0};    //osal_memcpy(afRxData, pkt->cmd.Data, pkt->cmd.DataLength);    HalUARTWrite(UART0, pkt->cmd.Data, pkt->cmd.DataLength);  }}




afIncomingMSGPacket_t表示无线数据包,数据就放在cmd结构体中。


接收的大概过程:当终端模块发送数据的时候,协调器模块底层接收到无线数据,会给我们应用层发一个AF_INCOMING_MSG_CMD的消息
,我们可以在这个消息里面处理接收到的数据。


在APP init方法中对串口的初始化相关代码及变量:

halUARTCfg_t uartConfig;uartConfig.configured           = TRUE;              // 2x30 don't care - see uart driver.uartConfig.baudRate             = SERIAL_APP_BAUD;uartConfig.flowControl          = FALSE;uartConfig.flowControlThreshold = SERIAL_APP_THRESH; // 2x30 don't care - see uart driver.uartConfig.rx.maxBufSize        = SERIAL_APP_RX_SZ;  // 2x30 don't care - see uart driver.uartConfig.tx.maxBufSize        = SERIAL_APP_TX_SZ;  // 2x30 don't care - see uart driver.uartConfig.idleTimeout          = SERIAL_APP_IDLE;   // 2x30 don't care - see uart driver.uartConfig.intEnable            = TRUE;              // 2x30 don't care - see uart driver.uartConfig.callBackFunc         = SerialApp_CallBack;// 串口回调函数HalUARTOpen(UART0, &uartConfig);#define UART0        0x00#define SERIAL_APP_TX_MAX    20static uint8  SerialApp_TxBuf[SERIAL_APP_TX_MAX+1];static uint8  SerialApp_TxLen;//串口回调函数static void SerialApp_CallBack(uint8 port, uint8 event){  (void)port;  if ((event&(HAL_UART_RX_FULL|HAL_UART_RX_ABOUT_FULL|HAL_UART_RX_TIMEOUT))&&!SerialApp_TxLen)  {    if (!SerialApp_TxLen && (SerialApp_TxLen = HalUARTRead(UART0, SerialApp_TxBuf, SERIAL_APP_TX_MAX))){       for(uint8 index = 1;index<SerialApp_TxLen;index++)        {           printf("%X ",SerialApp_TxBuf[index]);        }printf("\r\n");            }  }}


重要概念说明:

端点(endPoint):
1,它是一个字节(8个二进制位)编号的,是数据接收和发送的基本单元,在模块通信的时候,发送模块必须指定收发双方的网络地址和端点(针对单播)。
2,端点要使用,必须要和某个模块的任务挂勾定义。因为协调器拿到数据以后,是通过发送消息给应用层的,应用层是通过任务来处理的。
(取数据的时候是根据任务来的)
  
 首先每一个端点可以看成是一个字节数字编号的开有一个门的房间,数据最终的目标是进入到无线数据包指定的目标端点房间,而取无线数据
 这个相关的代码是在任务事件的处理函数里,而TI协议栈有那么多的任务事件处理函数,所以必须要指定在哪一个任务事件处理函数来取无
 线数据包里面的数据!

3,一个端点只能挂勾在一个任务上,而一个任务可以挂钩多个端点,且端点对所有任务是公用的,定义一个就少一个。
  假如一个端点如果挂钩了两个任务,那么接收模块处理任务的时候,这个时候同一个端点有多个任务事件处理函数去处理,不合理!!!
  一个任务挂多个端点,接收模块仅仅是判断到底该数据投递到哪个端点。
  
端点就相当于一个房间编号(对应代码里面的结构体),发送数据的时候,需要指明数据从哪个房间出去(源端点),并将数据投递哪个房间(目标端点)  

SimpleDescriptionFormat_t:
更加详细的描述商战的情况,就像描述一个房间里面有多少人之类的消息


端点的绑定最终要等afRegister()方法调用完成,才表示绑定完成

所以,数据包发送出去以后,首先目标协调器模块的网络地址0x0000对上了,协调器可以拿到这个无线数据包在底层的任务,
判断20号端点已经定义且绑定到了应用层的任务

簇(clusterID):(相当于房间里面的具体的人)
相当于端点房间里面的人,是接收最终的目标,这个东西是两个字节,在射频发送的时候,必须要指明要发到接模块哪个端点(哪个房间)、
哪个端点对应的哪个簇(房间里的哪一个人),发送模块不需要指定簇


  
  
  
   

























0 0
原创粉丝点击