您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 串口透传-打造无线串口模块
WeBee团队Zigbee组网实验教程17.串口透传-打造无线串口模块前言:串口透传,这个名词相信大家在看ZigBee相关资料时候经常会看到,透传到底是什么呢?电脑A和电脑B通过串口相连,相互发送信息,现在我们将电脑A和B连接ZigBee模块,再用串口收发信息,ZigBee的作用就相当于把有线信号转化成无线信号。这样我们电脑前面操作是一样的,但是已经变成了无线传输了,这就是串口透传!图1所示:2.4GPC1COM网蜂Zigbee模块PC2COM网蜂Zigbee模块图1串口透传网上的价格这么贵的东西原理又是怎样呢?我们能不能用自己的模块做一个呢?网蜂跟你说,完全没问题。实现平台:WeBeeCC2530模块及功能底板各两块(一个协调器,一个终端)图2WeBee团队Zigbee组网实验教程2实验现象:两台不同的PC机通过串口连接到网蜂开发板,打开串口调试助手,设置好波特率等参数。相互收发信息。没有2台电脑的也可以用同一台电脑的不同串口进行实验。实验讲解:实验依然使用我们熟悉的SampleApp.eww工程来进行。在前面我们曾做过串口实验和数据无线传输,这次实验也算是前面2个实验的一个结合。不过协议栈的串口接收有特定的格式,我们得了解一下它的传输机制。先理清我们要实现这个功能的流程:由于2台PC机所带的模块地位是相等的,所以两个模块的程序流程也一样了:1、ZigBee模块接收到从PC机发送信息,然后无线发送出去2、ZigBee模块接收到其它ZigBee模块发来的信息,然后发送给PC机我们打开Z-stack目录Projects\zstack\Samples\SampleApptest\CC2530DB里面的SampleApp.eww工程。这次实验我们基于协议栈的;SampleApp来进行。图3打开工程后,我们可以看到上一节说到workspace目录下比较重要的两个文件夹,Zmain和App。这里我们主要用到App,这也是用户自己添加自己代码的地方。主要在SampleApp.c和SampleApp.h中就可以了。WeBee团队Zigbee组网实验教程3图41、ZigBee模块接收到从PC机发送信息,然后无线发送出去以前我们做的都是CC2530给PC机串口发信息,还没接触过PC机发送给CC2530,现在我们就来完成这个任务。其主要代码在MT_UART.C中。我们之前协议栈串口实验对串口初始化时候已经有所了解了。我们在这个文件里找到串口初始化函数voidMT_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我们定义了ZTOOL_P1,故协议栈数据处理的函数是MT_UartProcessZToolData,进入这个函数定义。下边是对函数关键地方的解释。WeBee团队Zigbee组网实验教程4/********************************************************************@fnMT_UartProcessZToolData**@brief|SOP|DataLength|CMD|Data|FCS|*|1|1|2|0-Len|1|**ParsesthedataanddetermineeitherisSPIorjustsimplyserialdata*thensendthedatatocorrectplace(MTorAPP)**@paramport-UARTport*event-Eventthatcausesthecallback*@returnNone****************************************************************//*这个函数很长,具体说来就是把串口发来的数据包进行打包,校验,生成一个消息,发给处理数据包的任务。如果你看过MT的文档,应该知道如果用ZTOOL通过串口来沟通协议栈,那么发过来的串口数据具有以下格式:0xFE,DataLength,CM0,CM1,Datapayload,FCS翻译:0xFE:数据帧头DataLength:Datapayload的数据长度,以字节计,低字节在前;CM0:命令低字节;CM1:命令高字节;(ZTOOL软件就是通过发送一系列命令给MT实现和协议栈交互)Datapayload:数据帧具体的数据,这个长度是可变的,但是要和DataLength一致;FCS:校验和,从DataLength字节开始到Datapayload最后一个字节所有字节的异或按字节操作;也就是说,如果PC机想通过串口发送信息给CC2530,由于是使用默认的串口函数,所以您必须按上面的格式发送,否则CC2530是收不到任何东西的,这也是我们大家在调试串口接收时一直打圈的地方。尽管这个机制是非常完成的,也能校验串口数据,但是很明显,我们需要的是CC2530能直接接收到串口信息,然后一成不变的发成出去,相信你在聊QQ的时候也不希望在每句话前面加FE....的特定字符吧,而且还要自己计算校验码。于是我们就来个偷龙转凤,把改函数换成我们自己的串口处理函数,是不是很酷?当然,不过前提我们先要了解自带的这个函数。voidMT_UartProcessZToolData(uint8port,uint8event){……while(Hal_UART_RxBufLen(port))/*查询缓冲区读信息,也成了这里信息是否接收完的标志*/{HalUARTRead(port,&ch,1);WeBee团队Zigbee组网实验教程5/*一个一个地读,读完一个缓冲区就清1个了,?为什么这样呢,往下看*/switch(state)/*用上状态机了*/{caseSOP_STATE:if(ch==MT_UART_SOF)/*MT_UART_SOF的值默认是0xFE,所以数据必须FE格式开始发送才能进入下一个状态,不然永远在这里转圈*/state=LEN_STATE;break;caseLEN_STATE:LEN_Token=ch;tempDataLen=0;/*Allocatememoryforthedata*/pMsg=(mtOSALSerialData_t*)osal_msg_allocate(sizeof(mtOSALSerialData_t)+MT_RPC_FRAME_HDR_SZ+LEN_Token);/*分配内存空间*/if(pMsg)/*如果分配成功*/{/*Fillupwhatwecan*/pMsg-hdr.event=CMD_SERIAL_MSG;/*注册事件号CMD_SERIAL_MSG;,很有用*/pMsg-msg=(uint8*)(pMsg+1);/*定位数据位置*/………/*Makesureit'scorrect*/tmp=MT_UartCalcFCS((uint8*)&pMsg-msg[0],MT_RPC_FRAME_HDR_SZ+LEN_Token);if(tmp==FSC_Token)/*数据校验*/{osal_msg_send(App_TaskID,(byte*)pMsg);/*把数据包发送到OSAL层,很很重要*/}else{/*deallocatethemsg*/osal_msg_deallocate((uint8*)pMsg);WeBee团队Zigbee组网实验教程6/*清申请的内存空间*/}/*Resetthestate,sendordiscardthebuffersatthispoint*/state=SOP_STATE;/*状态机一周期完成*/………简单看了一下代码,串口从PC机接收到信息会做如下处理:1、接收串口数据,判断起始码是否为0xFE2、得到数据长度然后给数据包pMsg分配内存3、给数据包pMsg装数据4、打包成任务发给上层OSAL待处理5、释放数据包内存我们要做的是简化再简化。流程变成:1、接收到数据2、判断长度然后然后给数据包pMsg分配内存3、打包发送给上层OSAL待处理4、释放内存网蜂独家参考程序如下:1.voidMT_UartProcessZToolData(uint8port,uint8event)2.{3.uint8flag=0,i,j=0;//flag是判断有没有收到数据,j记录数据长度4.uint8buf[128];//串口buffer最大缓冲默认是128,我们这里用128.5.(void)event;//Intentionallyunreferencedparameter6.while(Hal_UART_RxBufLen(port))//检测串口数据是否接收完成7.{8.HalUARTRead(port,&buf[j],1);//把数据接收放到buf中9.j++;//记录字符数10.flag=1;//已经从串口接收到信息11.}12.if(flag==1)//已经从串口接收到信息13.{/*Allocatememoryforthedata*/14.//分配内存空间,为机构体内容+数据内容+1个记录长度的数据15.pMsg=(mtOSALSerialData_t*)osal_msg_allocate(sizeof16.(mtOSALSerialData_t)+j+1);17.//事件号用原来的CMD_SERIAL_MSG18.pMsg-hdr.event=CMD_SERIAL_MSG;WeBee团队Zigbee组网实验教程719.pMsg-msg=(uint8*)(pMsg+1);//把数据定位到结构体数据部分20.pMsg-msg[0]=j;//给上层的数据第一个是长度21.for(i=0;ij;i++)//从第二个开始记录数据22.pMsg-msg[i+1]=buf[i];23.osal_msg_send(App_TaskID,(byte*)pMsg);//登记任务,发往上层24./*deallocatethemsg*/25.osal_msg_deallocate((uint8*)pMsg);//释放内存26.}27.}由网蜂提供的代码可以知道,数据包中数据部分的格式是:datalen+data到这里,数据接收的处理函数已经完成了,接下来我们要做的就是怎么在任务中处理这个包内容呢?很简单,因为串口初始化是在SampleApp中进行的,任务号也是SampleApp的ID,所以当然是在SampleApp.C里面进行了。在SampleApp.C找到任务处理函数:uint16SampleApp_ProcessEvent(uint8task_id,uint16events),加入下面红色代码:uint16SampleApp_ProcessEvent(uint8task_id,uint16events){afIncomingMSGPacket_t*MSGpkt;(void)task_id;//Intentionallyunreferencedparameterif(events&SYS_EVENT_MSG){MSGpkt(afIncomingMSGPacket_t*)osal_msg_receive(SampleApp_TaskID);while(MSGpkt){switch(MSGpkt-hdr.event){caseCMD_SERIAL_MSG://串口收到数据后由MT_UART层传递过来的数据,用网蜂方法接收,编译时不定义MT相关内容,SampleApp_SerialCMD((mtOSALSerialData_t*)MSGpkt);break;解释:串
本文标题:串口透传-打造无线串口模块
链接地址:https://www.777doc.com/doc-6738248 .html