ZigBee组网学习笔记(六)--串口透传

来源:互联网 发布:h3c 绑定mac地址 编辑:程序博客网 时间:2024/05/19 15:22
程序流程:
1、 ZigBee 模块接收到从 PC机发送信息,然后无线发送出去
2、 ZigBee 模块接收到其它 ZigBee 模块发来的信息,然后发送给 PC机 


workspace 目录下比较重要的两个文件夹, Zmain 和 App。
这里我们主要用到 App,这也是用户自己添加自己代码的地方。
 
==========================================
初始化串口(参考协议栈串口实验)

1、

SampleApp.c

#include  "MT_UART.h" //串口头文件引用 

2、
SampApp.c

SampApp_Init()SampApp_TransID() = 0;////////////////MT_UartInit();////////////////


3、
void MT_UartInit()
uartConfig.baudRate             =MT_UART_DEFAULT_BAUDRATE;
uartConfig.flowControl          = MT_UART_DEFAULT_OVERFLOW;

#define MT_UART_DEFAULT_BAUDRATE         HAL_UART_BR_115200 //38400 #define MT_UART_DEFAULT_OVERFLOW       FALSE //TRUE 


4、
用 ZTOOL,串口 0。我们可以在 option——C/C++ 的 CompilerPreprocessor 里面看到,已经默认添加 ZTOOL_P1 预编译。
5、

void SampleApp_Init( uint8 task_id )MT_UartInit();////////////MT_UartRegisterTaskID(task_id);//登记任务号////////////

至此,就可以使用 HalUARTWrite(0, "Hello,world\n", 12); //(串口, 字符, 字符个数)  发送数据了。


==========================================
1、 ZigBee 模块接收到从 PC机发送信息,然后无线发送出去

MT_UART.c
void MT_UartInit ()#ifdefined (ZTOOL_P1) || defined (ZTOOL_P2)uartConfig.callBackFunc  =MT_UartProcessZToolData;///////#elifdefined (ZAPP_P1) || defined (ZAPP_P2)uartConfig.callBackFunc  = MT_UartProcessZAppData;#elseuartConfig.callBackFunc  = NULL;#endif


MT_UartProcessZToolData
串口发来的数据包进行打包,校验,生成一个消息,发给处理数据包的任务。

用 ZTOOL 通过串口来沟通协议栈,那么发过来的串口数据具有以下格式:
0xFE, DataLength, CM0, CM1, Data payload, FCS
翻译:
0xFE:数据帧头
DataLength: Datapayload 的数据长度,以字节计,低字节在前;205
CM0:命令低字节;
CM1:命令高字节; (ZTOOL 软件就是通过发送一系列命令给 MT 实现和协议栈交互)
Data payload:数据帧具体的数据,这个长度是可变的,但是要和DataLength 一致;
FCS :校验和,从 DataLength 字节开始到 Data payload 最后一个字节所有字节的异或按字节操作;
这样处理太复杂。。

串口从 PC 机接收到信息 
1、 接收串口数据,判断起始码是否为 0xFE
2、 得到数据长度然后给数据包 pMsg 分配内存
3、 给数据包 pMsg 装数据
4、 打包成任务发给上层 OSAL 待处理
5、 释放数据包内存 
 void MT_UartProcessZToolData ( uint8 port, uint8 event ) 
该函数换成我们自己的串口处理函数 

***************************************************
void MT_UartProcessZToolData ( uint8 port, uint8 event ){uint8 flag=0,i,j=0;   //flag是判断有没有收到数据,j记录数据长度uint8 buf[128];     //串口buffer最大缓冲默认是128,我们这里用128.(void)event;        // Intentionally unreferenced parameter  while (Hal_UART_RxBufLen(port)) //检测串口数据是否接收完成{HalUARTRead (port,&buf[j], 1);  //把数据接收放到buf中j++;                           //记录字符数flag=1;                      //已经从串口接收到信息} if(flag==1)       //已经从串口接收到信息  {   /* Allocate memory for the data *///分配内存空间,为结构体内容+数据内容+1个记录长度的数据pMsg = (mtOSALSerialData_t *)osal_msg_allocate( sizeof  ( mtOSALSerialData_t )+j+1);//事件号用原来的CMD_SERIAL_MSGpMsg->hdr.event = CMD_SERIAL_MSG;pMsg->msg = (uint8*)(pMsg+1); // 把数据定位到结构体数据部分pMsg->msg [0]= j;              //给上层的数据第一个是长度for(i=0;i<j;i++)                //从第二个开始记录数据 pMsg->msg [i+1]= buf[i];   osal_msg_send( App_TaskID, (byte *)pMsg );  //登记任务,发往上层/* deallocate the msg */osal_msg_deallocate ( (uint8 *)pMsg );      //释放内存}}

数据包中数据部分的格式是:datalen + data 
至此,数据接收的处理函数已经完成。
***************************************************
接下来要做的就是处理这个包的内容
在函数SampleApp_ProcessEvent里面加入
case CMD_SERIAL_MSG:  
SampleApp_SerialCMD((mtOSALSerialData_t *)MSGpkt);
break;
CMD_SERIAL_MSG在 #include "MT.h" 中,因此在SampleApp.c中添加头文件#include "MT.h" 
SampleApp.c
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )if ( events & SYS_EVENT_MSG )MSGpkt(afIncomingMSGPacket_t*)osal_msg_receive( SampleApp_TaskID );while ( MSGpkt ) switch ( MSGpkt->hdr.event )//串口收到数据后由MT_UART层传递过来的数据,用该方法接收,编译时不定义MT相关内容 case CMD_SERIAL_MSG:  SampleApp_SerialCMD((mtOSALSerialData_t *)MSGpkt);break;
解释:串口收到信息后,事件号 CMD_SERIAL_MSG 就会被登记,便进入case CMD_SERIAL_MSG: 
执行 SampleApp_SerialCMD((mtOSALSerialData_t *)MSGpkt); 
大家是不是很奇怪怎么在协议栈里找不到这个函数,当然了,我们那边只把他打包了,然登记任务,这个包是我们自己的,想怎么处理当然由自己决定,这个函数是信息无线发送出去。
***************************************************
自己定义该函数
void SampleApp_SerialCMD(mtOSALSerialData_t *cmdMsg){uint8 i,len,*str=NULL;     //len有用数据长度str=cmdMsg->msg;          //指向数据开头len=*str;                //msg里的第1个字节代表后面的数据长度/********打印出串口接收到的数据,用于提示*********/for(i=1;i<=len;i++)HalUARTWrite(0,str+i,1 ); HalUARTWrite(0,"\n",1 );//换行  /*******发送出去,同无线数据传输********/if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,SAMPLEAPP_COM_CLUSTERID,//自己定义一个len+1,                // 数据长度         str,                     //数据内容&SampleApp_TransID, AF_DISCV_ROUTE,AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ){}else{// Error occurred in request to send.} }

别忘了函数声明:
void SampleApp_SerialCMD(mtOSALSerialData_t *cmdMsg); 
***************************************************
SampleApp.h  定义
SAMPLEAPP_COM_CLUSTERID这个自己定义的 ID,用于接收方判别
//////////////#define SAMPLEAPP_MAX_CLUSTERS  3 //2//////////////#define SAMPLEAPP_PERIODIC_CLUSTERID 1#define SAMPLEAPP_FLASH_CLUSTERID 2///////////////#define SAMPLEAPP_COM_CLUSTERID 3///////////////



***************************************************

2、 ZigBee 模块接收到其它 ZigBee 模块发来的信息,然后发送给 PC机
 
SampleApp.c
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ){uint16 flashTime;switch ( pkt->clusterId ){uint8 i,len;//.....///////////////////////case SAMPLEAPP_COM_CLUSTERID:    //如果是串口透传的信息len=pkt->cmd.Data[0];for(i=0;i<len;i++)HalUARTWrite(0,&pkt->cmd.Data[i+1],1);//发给PC机      HalUARTWrite(0,"\n",1);               // 回车换行      break;///////////////////////}}




最后还要修改预编译,注释掉 MT 层的内容。这里注意,选择了协调器、路由器、或者终端编译时
都要修改 options 。
参考如下:
ZTOOL_P1
xMT_TASK
xMT_SYS_FUNC
xMT_ZDO_FUNC
xLCD_SUPPORTED=DEBUG


接下来烧写程序到板子上面就可以了。



0 0
原创粉丝点击