ZStack同时使用两个串口

协议栈版本:ZStack-2007(ZStack-CC2530-2.5.1a)

芯片型号:CC2530

 

 

我们在使用ZigBee时通常只用到一个串口,但是在某些情况下希望同时使用两个串口。ZStack默认只能使用一个串口。不过我们可以通过修改协议栈内容来同时使用两个串口。

 

首先来看一下为什么ZStack只能使用一个串口()

MT_UART.h头文件中:

#if defined (MT_UART_DEFAULT_PORT)

  HalUARTOpen (MT_UART_DEFAULT_PORT, &uartConfig);

#else

  /* Silence IAR compiler warning */

  (void)uartConfig;

#endif

 

//定义了ZTOOL_P1

#if defined (ZTOOL_P1) || defined (ZTOOL_P2)      //DMA方式

  #define MT_UART_DEFAULT_PORT           ZTOOL_PORT

#elif defined (ZAPP_P1) || defined (ZAPP_P2) //ISR方式

  #define MT_UART_DEFAULT_PORT           ZAPP_PORT

#endif

 

 

#if defined (ZTOOL_P1)

  #define ZTOOL_PORT   HAL_UART_PORT_0//串口0

#elif defined (ZTOOL_P2)

  #define ZTOOL_PORT  HAL_UART_PORT_1//串口1

#else

  #undef ZTOOL_PORT

#endif

 

该头文件中定义了一个默认UART串口端口,从第二段  #if defined (ZTOOL_P1) || defined (ZTOOL_P2)      //DMA方式

开始,由于使用了if-else结构,如果定义了ZTOOL_P1或者ZTOOL_P2,那么默认端口为ZTOOL_PORT,在这种情况下ISR方式就不会再出现了。如果没有使用DMA方式,并且定义了ZAPP_P1或者ZAPP_P2,则采用ISR方式。

接下来看第三段:如果定义了ZTOOL_P1,则ZTOOL_PORTHAL_UART_PORT_0串口0,否则如果定义了ZTOOL_P2,则为串口1。该结构仍采用了if-else结构,也就是说使用了串口0就不会再用到串口1

那么我们可以得出这样的结论,使用了DMA方式就不能再用ISR方式,使用了串口0就不能再用串口1。当然这只是默认串口,默认串口只能有一个。这个似乎和使用两个串口没什么关系,只是使用两个串口就不能再采用默认串口这一说了。

 

下面再看hal_board_cfg.h中的这样一段:

//如果在没有定义HAL_UART且定义了ZAPP_PZAPP_P2ZTOOL_P1ZTOOL_P2那么定义HAL_UART TRUE;否则定义HAL_UART FALSE

#ifndef HAL_UART

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

#define HAL_UART TRUE

#else

#define HAL_UART FALSE

#endif

#endif

 

 

//如果HAL_UART为真并且没有定义HAL_UART_DMA,并且HAL_DMA为真并且定义了ZAPP_P2 ZTOOL_P2那么 定义HAL_UART_DMA  2否则定义HAL_UART_DMA  1

#if HAL_UART

#ifndef  HAL_UART_DMA

#if HAL_DMA

#if (defined ZAPP_P2) || (defined ZTOOL_P2)

#define HAL_UART_DMA  2

#else

#define HAL_UART_DMA  1

#endif

#else

#define HAL_UART_DMA  0

#endif

#endif

 

 

#ifndef HAL_UART_ISR

#if HAL_UART_DMA        // Default preference for DMA over ISR.

#define HAL_UART_ISR  0

#elif (defined ZAPP_P2) || (defined ZTOOL_P2)

#define HAL_UART_ISR  2

#else

#define HAL_UART_ISR  1

#endif

#endif

 

第一段的意思是如果定义了ZTOOL_P1等四个当中的一个,那么就HAL_UART即为真。即串口可用。

在该头文件上仔细找可以找到该句:

#ifndef HAL_DMA

#define HAL_DMA TRUE

#endif

那么对于第二段,我们可以得出这样的结论:只要是定义了ZTOOL_P1等四个当中的一个,那么HAL_UART_DMA的逻辑值就为1否则为0

 

而对于第三段只要HAL_UART_DMA的逻辑值为1,则ISR不可用,注释意为默认DMA优先级高于ISR

所以对于ZStack来说默认只能使用一个串口。那么想要使用两个串口该怎么办呢?当然是要修改上面的代码了。

 

ZigBee使用两个串口的方法:

 

修改hal_board_cfg.h中的第二三段代码如下:

 

#if HAL_UART

//Always prefer to use DMA over ISR.

#if HAL_DMA

#ifndef HAL_UART_DMA

#if (defined ZAPP_P1)||(defined ZTOOL_P1)

#define HAL_UART_DMA 1

#elif(defined ZAPP_P2)||(defined ZTOOL_P2)

#define HAL_UART_DMA 2

#else 

#define HAL_UART_DMA 1

#endif

#endif

#define HAL_UART_ISR 2

#else

#ifndef HAL_UART_ISR

#if(defined ZAPP_P1)||(defined ZTOOL_P1)

#define HAL_UART_ISR 1

#elif(defined ZAPP_P2)||(defined ZTOOL_P2)

#define HAL_UART_ISR 2

#else

#define HAL_UART_ISR 1

#endif

#endif

#define HAL_UART_DMA 0

#endif

(该段代码摘录自网上,使用时定义ZATOOL_P1即可,这样选择了串口0DMA方式,串口1中断方式,如果定义ZAPP_P2可能会产生逻辑问题)

修改后意为如果使用了DMA,则定义相应的通道为DMA方式,同时定义串口1采用中断方式,如果没有定义DMA,则使用中断方式。

修改完以后协议栈已支持同时使用两个串口,但是想要使用还得对串口进行初始化。自带的串口初始化不作改动,默认串口0采用DMA方式,另外需要写一个串口1的初始化函数。函数如下:

void MT_Uart1Init ()

{

  halUARTCfg_t uartConfig1;

 

  /* Initialize APP ID */

  App_TaskID = 0;

 

  /* UART Configuration */

  uartConfig1.configured           = TRUE;

  uartConfig1.baudRate             = MT_UART_DEFAULT_BAUDRATE;

  uartConfig1.flowControl          = MT_UART_DEFAULT_OVERFLOW;

  uartConfig1.flowControlThreshold = 32;

  uartConfig1.rx.maxBufSize        = 32;

  uartConfig1.tx.maxBufSize        = 32;

  uartConfig1.idleTimeout          = 6;

  uartConfig1.intEnable            = TRUE;

  uartConfig1.callBackFunc         = MT_UartProcessZToolData;

 

  /* Start UART */

  HalUARTOpen (HAL_UART_PORT_1, &uartConfig1);

  /* Silence IAR compiler warning */

 

  /* Initialize for ZApp */

#if defined (ZAPP_P1) || defined (ZAPP_P2)

  /* Default max bytes that ZAPP can take */

  MT_UartMaxZAppBufLen  = 1;

  MT_UartZAppRxStatus   = MT_UART_ZAPP_RX_READY;

#endif

 

}

注意红色字体部分:  HalUARTOpen (HAL_UART_PORT_1, &uartConfig1);

初始化打开串口为HAL_UART_PORT_1其他参数有结构体uartConfig1传给回调函数。当然还需要将该初始化注册到用户应用层。即在用户应用层初始化函数中(例:void SampleApp_Init( uint8 task_id )注:不同的程序应用层初始化函数不同)调用该函数即可。

 

当然还需要回调函数。两个串口初始化均采用同样的回调函数,测试显示只能使用一个回调函数。所以对于串口事件均指定一个处理事件,如果想要两个串口分别对应不同的串口事件,则做如下修改:

 

        if (pMsg)

        {

          /* Fill up what we can */

          if(port == HAL_UART_PORT_0)

          {

            pMsg->hdr.event = CMD_SERIAL_MSG;

          }

          else

          {

            pMsg->hdr.event = CMD_SERIAL1_MSG; 

          }

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

          pMsg->msg[MT_RPC_POS_LEN] = LEN_Token;

          state = CMD_STATE1;

        }

 

在用户应用层加上相应的触发事件及处理函数即可。

由于板子还没有出来,还没有进行测试。

板子测试成功。

 

 

你可能感兴趣的:(ZStack同时使用两个串口)