原创 SimpleApp例子串口出现乱码的原因?

2008-12-12 14:04 3329 3 3 分类: 通信

问题出现可以参看从零开始学习ZSTACK9文章


http://www.yyytech.cn/Tech/Read.aspx?id=264


Z9-1.jpg


提问:


“每次发射开始时候会发送乱码出来? <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


我跟踪代码发现是DMA开始的时候发出来的?


难道是FIFO里面的随机数?


但是为什么每次都一样呢?


百思不得其解!!!!寻求帮忙~


 解答:


下面我们来跟踪下串口发送程序:


1、首先看看SimpleApp.c文件的函数zb_ReceiveDataIndication()最后一句话为向串口发数据的。


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />



2debug_str


void debug_str( byte *str_ptr )


{


  mtDebugStr_t *msg;


  byte mln;


  byte sln;


  // Text string length


  sln = (byte)osal_strlen( (void*)str_ptr );


  // Debug string message length


  mln = sizeof ( mtDebugStr_t ) + sln;


  // Get a message buffer to build the debug message


  msg = (mtDebugStr_t *)osal_msg_allocate( mln );


  if ( msg )


  {


    // Message type, length


    msg->hdr.event = CMD_DEBUG_STR;


    msg->sln = sln;


    // Append message, no terminator


    msg->pString = (uint8 *)(msg+1);


    osal_memcpy ( msg->pString, str_ptr, sln );


    osal_msg_send( MT_TaskID, (uint8 *)msg );


  }


} // debug_str()


这里我比较关系结构


typedef struct


{


  osal_event_hdr_t  hdr;


  uint8             sln; // String length


  uint8             *pString;


} mtDebugStr_t;


这个结构有三个参数:事件句柄、长度、数据指针


 


3osal_msg_send( MT_TaskID, (uint8 *)msg );


byte osal_msg_send( byte destination_task, byte *msg_ptr )


{


  if ( msg_ptr == NULL )


    return ( INVALID_MSG_POINTER );


  if ( destination_task >= tasksCnt )


  {


    osal_msg_deallocate( msg_ptr );


    return ( INVALID_TASK );


  }


  // Check the message header


  if ( OSAL_MSG_NEXT( msg_ptr ) != NULL ||


       OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )


  {


    osal_msg_deallocate( msg_ptr );


    return ( INVALID_MSG_POINTER );


  }


  OSAL_MSG_ID( msg_ptr ) = destination_task;


 


  // queue message


  osal_msg_enqueue( &osal_qHead, msg_ptr );


  // Signal the task that a message is waiting


  osal_set_event( destination_task, SYS_EVENT_MSG );


  return ( ZSUCCESS );


}


 


这个函数就是发送事件,这里不做讨论,因为这涉及到OS的内容,比较麻烦!


只要知道这个时间发送到MT去了,然后只需要去看看MT的处理事件函数就可以了。


4MTEL.C


UINT16 MT_ProcessEvent( byte task_id, UINT16 events )


{


  uint8 *msg_ptr;


  // Could be multiple events, so switch won't work


  if ( events & SYS_EVENT_MSG )


  {


    while ( (msg_ptr = osal_msg_receive( MT_TaskID )) )


    {


      MT_ProcessCommand( (mtOSALSerialData_t *)msg_ptr );


    }


    // Return unproccessed events


    return (events ^ SYS_EVENT_MSG);


  }


#if defined (ZTOOL_P1) || defined (ZTOOL_P2)


  if ( events & MT_ZTOOL_SERIAL_RCV_BUFFER_FULL )


  {


    // Do sometype of error processing


    MT_SendErrorNotification(RECEIVE_BUFFER_FULL);


    // Return unproccessed events


    return (events ^ MT_ZTOOL_SERIAL_RCV_BUFFER_FULL);


  }


#endif


  // Discard or make more handlers


  return 0;


} /* MT_ProcessEvent() */


 


5MT_ProcessCommand( (mtOSALSerialData_t *)msg_ptr );


void MT_ProcessCommand( mtOSALSerialData_t *msg )


{


  byte deallocate;


#if defined (ZTOOL_P1) || defined (ZTOOL_P2)


  byte *msg_ptr;


  byte len;


 


  // A little setup for AF, CB_FUNC and MT_SYS_APP_RSP_MSG


  msg_ptr = msg->msg;


#endif // ZTOOL


 


  deallocate = true;


 


  // Use the first byte of the message as the command ID


  switch ( msg->hdr.event )


  {


#if defined (ZTOOL_P1) || defined (ZTOOL_P2)


    case CMD_SERIAL_MSG:


      MT_ProcessSerialCommand( msg->msg );


      break;


 


    case CMD_DEBUG_MSG:


      MT_ProcessDebugMsg( (mtDebugMsg_t *)msg );


      break;


    case CMD_DEBUG_STR:


      MT_ProcessDebugStr( (mtDebugStr_t *)msg );


      break;


    case CB_FUNC:


      /*


        Build SPI message here instead of redundantly calling MT_BuildSPIMsg


        because we have copied data already in the allocated message


      */


      /* msg_ptr is the beginning of the intended SPI message */


      len = SPI_0DATA_MSG_LEN + msg_ptr[DATALEN_FIELD];


      /*


        FCS goes to the last byte in the message and is calculated over all


        the bytes except FCS and SOP


      */


      msg_ptr[len-1] = SPIMgr_CalcFCS( msg_ptr + 1 , (byte)(len-2) );


 


#ifdef SPI_MGR_DEFAULT_PORT


      HalUARTWrite ( SPI_MGR_DEFAULT_PORT, msg_ptr, len );


#endif


      break;


#if !defined ( NONWK )


    case MT_SYS_APP_RSP_MSG:


      len = SPI_0DATA_MSG_LEN + msg_ptr[DATALEN_FIELD];


      MTProcessAppRspMsg( msg_ptr, len );


      break;


#endif  // NONWK


#endif  // ZTOOL


    default:


      break;


  }


  if ( deallocate )


  {


    osal_msg_deallocate( (uint8 *)msg );


  }


}


这里的事件句柄为:CMD_DEBUG_STR;


 


6MT_ProcessDebugStr( (mtDebugStr_t *)msg );


void MT_ProcessDebugStr( mtDebugStr_t *dstr )


{


  byte *msg_ptr;


 


  // Get a message buffer to build the debug message


  msg_ptr = osal_mem_alloc( (byte)(SPI_0DATA_MSG_LEN + dstr->sln) );


  if ( msg_ptr )


  {


#ifdef SPI_MGR_DEFAULT_PORT


    MT_BuildSPIMsg( SPI_RESPONSE_BIT | SPI_SYS_STRING_MSG, msg_ptr, dstr->sln, dstr->pString );


    HalUARTWrite ( SPI_MGR_DEFAULT_PORT, msg_ptr, SPI_0DATA_MSG_LEN + dstr->sln );


#endif


    osal_mem_free( msg_ptr );


  }


}


 


7MT_BuildSPIMsg


 


void MT_BuildSPIMsg( UINT16 cmd, byte *msg, byte dataLen, byte *pData )


{


  byte *msgPtr;


  *msg++ = SOP_VALUE;


   msgPtr = msg;


  *msg++ = (byte)(HI_UINT16( cmd ));


  *msg++ = (byte)(LO_UINT16( cmd ));


  if ( pData )


  {


    *msg++ = dataLen;


    msg = osal_memcpy( msg, pData, dataLen );


  }


  else


  *msg++ = 0;


  *msg = SPIMgr_CalcFCS( msgPtr, (byte)(3 + dataLen) );


}


这里可以看到MSG第一个字节为:SOP_VALUE


#define SOP_VALUE       0x02


第二、三个字节为:SPI_RESPONSE_BIT | SPI_SYS_STRING_MSG,


#define SPI_RESPONSE_BIT                0x1000


#define SPI_SYS_STRING_MSG              0x0015


最后结果为:0x1015


第四个字节为:*msg++ = dataLen;数据长度


最后一个字节为*msg = SPIMgr_CalcFCS( msgPtr, (byte)(3 + dataLen) );


校验!!!!!!


 


8HalUARTWrite


发送数据到串口!!!


 


提问:



麻烦你看下截图:我仿真完 *msg++ = SOP_VALUE; msg[0]却=0x00

                         等仿真到如图却变成了1015   02怎么没了?

 

点击看大图

 

解答:


找到问题原因了。

因为*MSG=2之后呢,MSG++了,所以此时的MSG[0]已经是之前的*(MSG+1)了。建议用存储器观察!

 

点击看大图

 

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条