zigbee串口透明传输

来源:互联网 发布:淘宝卖零食的店铺 编辑:程序博客网 时间:2024/04/24 05:19

使用的协议栈版本信息: ZigBee2006\ZStack-1.4.3-1.2.1

因为用现在这模块SerialApp没做成功,上电后按键没反应……两块无线龙小板子已经买来N年了.
自己想在SampleApp例子基础上修改实现串口透明传输:

串口调试助手1<————>模块1   <-----OTA----->  模块2<————>串口调试助手2

 

程序修改主要如下:
****************************************************************************************
****************************************************************************************

1、
宏定义事件  #define UART_RX_CB_EVT   0x0002  (SampleApp.h)

全局变量声明: (SPIMgr.h)
extern  uint8  rxlen;        //接收数据长度
extern  uint8*  databuf; 
//接收数据指针

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

2、
串口回调函数rxCB: (SPIMgr.c,直接在SPIMgr_Init()中进行修改)
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
  uartConfig.callBackFunc         = rxCB; 
//uartConfig.callBackFunc         = SPIMgr_ProcessZToolData;  //回调函数

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

3、十六进制转字符函数 (SampleApp.c)  这两个函数由青竹]编写.
 
uint8 hextoword1(uint8 t )
{
  uint8 abc;
  uint8 cba;
  uint8 xx1;
  abc=t;
  cba=0xf0;
  abc=(abc&cba)>>4;
  if(abc<10)
  {
    xx1=abc+48;
  }
  else
  {
    xx1=abc+55;
  }
  return xx1;
}
uint8 hextoword2(uint8 t)
{
  uint8 abc;
  uint8 cba;
  uint8 xx2;
  abc=t;
  cba=0x0f;
  abc=abc&cba;
  if(abc<10)
  {
    xx2=abc+48;
  }
  else
  {
    xx2=abc+55;
  }
  return xx2;
}

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

4、定义串口回调函数rxCB()  (SPIMgr.c)

static void rxCB( uint8 port, uint8 event )
{
//  uint8  rxlen;    //接收数据长度
//  uint8*  dataybuf;//接收数据块指针

  extern uint8 SampleApp_TaskID;
  uint16 short_ddr;
  uint8 short_ddr_H;
  uint8 short_ddr_L;
//  uint8 *pointer1;
//  uint8 word_buffer[8];

  short_ddr=NLME_GetShortAddr();
  short_ddr_H=(uint8)((short_ddr&0xff00)>>8);
  short_ddr_L=(uint8)short_ddr;
  rxlen=Hal_UART_RxBufLen(SPI_MGR_DEFAULT_PORT);  //接收缓冲区数据长度,字节为单位
  databuf=osal_mem_alloc(rxlen+1+2);   //多分配3字节,分配如下
  databuf[0]=rxlen;                           //一字节存放数据长度
  databuf[1]=short_ddr_H;              //一字节存放源地址高8位
  databuf[2]=short_ddr_L;              //一字节存放源地址低8位
  //databuf[rxlen+1]='\n';                    //一字节存放换行符
  HalUARTRead ( SPI_MGR_DEFAULT_PORT, databuf+3, rxlen);
//读接收缓冲区数据到内存databuf+3

  /* 回显数据(测试用)
  word_buffer[0]='l';
  word_buffer[1]='e';
  word_buffer[2]='n';
  word_buffer[3]=':'; 
  word_buffer[4]=databuf[0]/100+48;
  word_buffer[5]=(databuf[0]%100)/10+48;
  word_buffer[6]=databuf[0]%10+48;
  word_buffer[7]='\n';
  pointer1=word_buffer;
  //  HalUARTWrite()写入串口正确说明数据已经正确地存储在databuf中!
  HalUARTWrite ( SPI_MGR_DEFAULT_PORT, pointer1, 8 ); 
  HalUARTWrite ( SPI_MGR_DEFAULT_PORT, databuf+1, rxlen+1 );//把数据送串口输出
  */ 
 
if(!rxlen)
    osal_mem_free( databuf );  //释放内存 
    osal_set_event(SampleApp_TaskID,UART_RX_CB_EVT);
//  rxCB_to_SampleApp( databuf, rxlen );
}

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

5、添加:事件处理函数 (SampleApp.c)
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
{
  afIncomingMSGPacket_t *MSGpkt; 
 
//  显示网络地址变量
    uint16 short_ddr;
    uint8 yy1;
    uint8 yy2;
    uint8 str_1[ ]="my short address is:";
#if defined(ZDO_COORDINATOR)
    uint8 str_2[ ]="build the network successfully";
#else
    uint8 str_2[ ]="join the network successfully ";
#endif
    uint8 str_3[ ]={'\n'};
    uint8 shortaddr[7];
    uint8 *pointer1;
    uint8 *pointer2;
    uint8 *pointer3;
    uint8 *pointer4;

    …………(省略)


/*1、接收串口信息在SampleApp_MessageMSGCB()上进行修改*/
        case AF_INCOMING_MSG_CMD:          
          SampleApp_MessageMSGCB( MSGpkt );
          break;

 

/*2、设备建网/入网成功则显示本地网络地址*/
        case ZDO_STATE_CHANGE: 
          SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
          if ( (SampleApp_NwkState == DEV_ZB_COORD)
              || (SampleApp_NwkState == DEV_ROUTER)
              || (SampleApp_NwkState == DEV_END_DEVICE) )
          {
            //显示本地网络地址
            short_ddr=NLME_GetShortAddr();
            yy1=(uint8)((short_ddr&0xff00)>>8);
            yy2=(uint8)short_ddr;
            shortaddr[0]=48;
            shortaddr[1]=120;
            shortaddr[2]=hextoword1(yy1);
            shortaddr[3]=hextoword2(yy1);
            shortaddr[4]=hextoword1(yy2);
            shortaddr[5]=hextoword2(yy2);
            shortaddr[6]='\n';
            pointer1=&shortaddr[0];
            pointer2=&str_1[0];
            pointer3=&str_2[0];
            pointer4=&str_3[0];
            HalUARTWrite(0,pointer4,1);
            HalUARTWrite(0,pointer3,29);
            HalUARTWrite(0,pointer4,1);           
            HalUARTWrite(0,pointer2,20);           
            HalUARTWrite(0,pointer1,7);
            HalUARTWrite(0,pointer4,1);
       //***************************************
          }
          else
          {
            // Device is no longer in the network
          }
          break;

    …………(省略)


/*3、对接收的串口数据进行处理*/
  if ( events & UART_RX_CB_EVT )  //串口数据处理
  { 

    SampleApp_SPI_SendData( databuf, rxlen+1+2 ); 
    return (events ^ UART_RX_CB_EVT);
  }
}

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

6、定义AF层数据处理函数SampleApp_MessageMSGCB()  (SampleApp.c)
   默认采用的簇ID为SAMPLEAPP_PERIODIC_CLUSTERID

void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
  uint16 flashTime;
  uint16 short_ddr;
  uint8 *pointer1;
  uint8 *pointer2;
  uint8 *pointer3;
  uint8 *pointer4;
  uint8 *pointer5;
  uint8 *pointer6;
  uint8 *pointer7;
  uint8 *pointer8;
  uint8 *pointer9;
 
  uint8 str_1[ ]="Source address:";
  uint8 str_2[ ]="Destination address:";
  uint8 str_3[ ]="Data length:";
  uint8 str_4[ ]="Data:";
  uint8 str_5[ ]={'\n'};
 
  pointer1=&str_1[0];
  pointer2=&str_2[0];
  pointer3=&str_3[0];
  pointer4=&str_4[0];
  pointer9=&str_5[0];
 
  uint8 Src_short_ddr_H;
  uint8 Src_short_ddr_L;
  uint8 Des_short_ddr_H;
  uint8 Des_short_ddr_L;
 
  uint8 word_buffer[4];
  uint8 Src_shortaddr[7];
  uint8 Des_shortaddr[7];
 
  switch ( pkt->clusterId ) //判断簇ID
  {
    case SAMPLEAPP_PERIODIC_CLUSTERID:
      /*####################################################*/
//      flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
//      HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );

     
      pointer5=&(pkt->cmd.Data[3]);       
  //pointer5:具体数据首地址

      word_buffer[0]=(pkt->cmd.Data[0])/100+48;
      word_buffer[1]=((pkt->cmd.Data[0])%100)/10+48;
      word_buffer[2]=(pkt->cmd.Data[0])%10+48;
      word_buffer[3]='\n';
      pointer6=word_buffer;                   
  //pointer6:数据长度

//----------------
      Src_short_ddr_H=pkt->cmd.Data[1];
      Src_short_ddr_L=pkt->cmd.Data[2];

      Src_shortaddr[0]=48;
      Src_shortaddr[1]=120;
      Src_shortaddr[2]=hextoword1(Src_short_ddr_H);
      Src_shortaddr[3]=hextoword2(Src_short_ddr_H);
      Src_shortaddr[4]=hextoword1(Src_short_ddr_L);
      Src_shortaddr[5]=hextoword2(Src_short_ddr_L);
      Src_shortaddr[6]='\n';
      pointer7=&Src_shortaddr[0];         //pointer7:源地址
//----------------
      short_ddr=NLME_GetShortAddr();
      Des_short_ddr_H=(uint8)((short_ddr&0xff00)>>8);
      Des_short_ddr_L=(uint8)short_ddr;
      Des_shortaddr[0]=48;
      Des_shortaddr[1]=120;
      Des_shortaddr[2]=hextoword1(Des_short_ddr_H);
      Des_shortaddr[3]=hextoword2(Des_short_ddr_H);
      Des_shortaddr[4]=hextoword1(Des_short_ddr_L);
      Des_shortaddr[5]=hextoword2(Des_short_ddr_L);
      Des_shortaddr[6]='\n';
      pointer8=&Des_shortaddr[0];       //pointer8:目的地址
 
//----------------     
      HalUARTWrite ( 0, pointer1, 15 );   //源地址
      HalUARTWrite ( 0, pointer7, 7 );
     
      HalUARTWrite ( 0, pointer2, 20 );   //目的地址
      HalUARTWrite ( 0, pointer8, 7 );
       
      HalUARTWrite ( 0, pointer3, 12 );   //数据长度
      HalUARTWrite ( 0, pointer6, 4 );
     
      HalUARTWrite ( 0, pointer4, 5 );    //具体数据    
      HalUARTWrite ( 0, pointer5, pkt->cmd.Data[0] );  //pkt->cmd.Data[0]=rxlen,为原始长度
     
      HalUARTWrite ( 0, pointer9, 1 );    //换行符
      HalUARTWrite ( 0, pointer9, 1 );
     
      //pointer1=&(pkt->cmd.Data[3]);
      //HalUARTWrite ( 0, pointer1, 6 );
      /*####################################################*/

      break;

    case SAMPLEAPP_FLASH_CLUSTERID://flash
      flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
      HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
      break;
  }
}

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

7、定义串口数据处理函数SampleApp_SPI_SendData()  (SampleApp.c)
  我只有两个节点,所以这里采用最简单的单点传送方式.下载协调器程序时目标地址改为0x796F,下载终端程序时目标地址改为0x0000.默认ClusterID为SAMPLEAPP_PERIODIC_CLUSTERID.

void SampleApp_SPI_SendData( uint8 *buf, uint8 len )
{

  SampleApp_SPI_SendData_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
  SampleApp_SPI_SendData_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
  SampleApp_SPI_SendData_DstAddr.addr.shortAddr = 0x796F;  //0x796F;0x0000
 
//  SampleApp_SendPeriodicMessage(); //测试用
 
  if ( AF_DataRequest( &SampleApp_SPI_SendData_DstAddr,
                         (endPointDesc_t *)&SampleApp_epDesc,
                          SAMPLEAPP_PERIODIC_CLUSTERID,
                          len, buf,
                          &SampleApp_TransID,
                          0,
                          AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
  {
    osal_mem_free( databuf );  //必须释放内存,不然造成溢出!
  }
  else
  {
    osal_mem_free( databuf );
  }
}

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

编译情况:

zigbee串口透明传输 - 小峰 - happy~ 

 

通信结果1:(关于开头的乱码说明参考后篇记录)

zigbee串口透明传输 - 小峰 - happy~
 

 通信结果2:

zigbee串口透明传输 - 小峰 - happy~

 

最大数据只能达到52字节:(但在修改程序过程中,达到过83字节;等修改完整后只有52字节了):

zigbee串口透明传输 - 小峰 - happy~
 
 
测试 SampleApp_SPI_SendData()中的osal_mem_free( databuf ).如果不把databuf释放,则数据只能发送几次就停止.下面是添加osal_mem_free( databuf )后两边串口自动发送,测试时间>5分钟,收发一直保持稳定.

 zigbee串口透明传输 - 小峰 - happy~

 

实物连接:

zigbee串口透明传输 - 小峰 - happy~

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

注:
串口调试助手A<—>节点A<—>收发----------收发<—>节点B<—>串口调试用手B
若串口调试助手A发数据串口调试助手B无反应,在串口配置以及程序编译正确的前提下可参考以下四步:
1、节点A是否正确接收串口发送的数据,可以通过串口回显数据进行判断
2、节点A是否成功发送数据,可以在成功发送数据的程序后添加一LED闪烁指令以帮助判断
3、节点B是否成功接收数据,可以在成功接收数据的程序后添加一LED闪烁指令以帮助判断
4、节点B是否把接收数据正确发往串口,可以自己在节点B设置发送一些数据以进行判断

我起初也是一堆错误,就是这样一块一块去测试的~
今天'阿弥陀佛'同学提了个编译错误的问题:
Error[e27]: Entry "MT_NwkCommandProcessing::?relay" in module MT_NWK ( C:\Texas Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Samples\SampleApp\CC2430DB\CoordinatorDB\Obj\MT_NWK.r51 ) redefined in module SampleApp ( C:\Texas 
Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Samples\SampleApp\CC2430DB\CoordinatorDB\Obj\SampleApp.r51 )
类似我以前也碰到过,但已经忘记怎么把它搞定的,
这个链接http://bbs.lierda.com/showthread.php?p=100430里的内容也不甚明白,但'阿弥陀佛'在所调用的函数MT_NwkCommandProcessing()前面加上static搞定,但有警告.有理解的朋友烦请解释下~3Q!

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

说明:
1、本文为个人学习笔记,仅供参考,随时更新
2、程序均由本人编写(除十六进制转字符函数由青竹提供外)
3、欢迎交流,转载请注明出处,谢谢!

更新:2010.7.30 /2010.11.26                                                       2010.7.29  ~XF

 上面为初始程序,有很多地方冗余,一些指针和变量可以优化删除掉的,请自行修改,或参见zigbee组网小实验2—相关源代码1,这里我不修正了。