【转自小峰博客】zigbee串口透明传输

使用的协议栈版本信息: 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)
#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 );
  }
}

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

编译情况:





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



通信结果2:





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




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




实物连接:




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

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

 

这是本人看到的转载!!!

 

posted @ 2011-04-27 09:21  雪帕  阅读(2943)  评论(0编辑  收藏  举报