串口收发数据1



1.Zigbee协议栈中,halUARTCfg_t结构体是如何定义的?

2.串口是如何初始化的?

3.发送给串口的数据时如何接收的?

4.串口是如何向PC机发送数据的?

这些问题涉及三个函数:HalUARTOpen()、HalUARTRead()、HalUARTWrite()

HalUARTOpen()函数原型如下:

uint8 HalUARTOpen(uint8 port, halUARTCfg_t *config)

{

  (void)port;

  (void)config;

 

#if (HAL_UART_DMA == 1)

  if (port == HAL_UART_PORT_0)  HalUARTOpenDMA(config);

#endif

#if (HAL_UART_DMA == 2)

  if (port == HAL_UART_PORT_1)  HalUARTOpenDMA(config);

#endif

#if (HAL_UART_ISR == 1)

  if (port == HAL_UART_PORT_0)  HalUARTOpenISR(config);

#endif

#if (HAL_UART_ISR == 2)

  if (port == HAL_UART_PORT_1)  HalUARTOpenISR(config);

#endif

#if (HAL_UART_USB)

  HalUARTOpenUSB(config);

#endif

  

  return HAL_UART_SUCCESS;

}

该函数实际上是调用了HalUARTOpenDMA函数,HalUARTOpenDMA函数原型如下:

static void HalUARTOpenDMA(halUARTCfg_t *config)

{

  dmaCfg.uartCB = config->callBackFunc;

  // Only supporting subset of baudrate for code size - other is possible.

  HAL_UART_ASSERT((config->baudRate == HAL_UART_BR_9600) ||

                  (config->baudRate == HAL_UART_BR_19200) ||

                  (config->baudRate == HAL_UART_BR_38400) ||

                  (config->baudRate == HAL_UART_BR_57600) ||

                  (config->baudRate == HAL_UART_BR_115200));

  

  if (config->baudRate == HAL_UART_BR_57600 ||

      config->baudRate == HAL_UART_BR_115200)

  {

    UxBAUD = 216;

  }

  else

  {

    UxBAUD = 59;

  }

  

  switch (config->baudRate)

  {

    case HAL_UART_BR_9600:

      UxGCR = 8;

      dmaCfg.txTick = 35; // (32768Hz / (9600bps / 10 bits))

                          // 10 bits include start and stop bits.

      break;

    case HAL_UART_BR_19200:

      UxGCR = 9;

      dmaCfg.txTick = 18;

      break;

    case HAL_UART_BR_38400:

      UxGCR = 10;

      dmaCfg.txTick = 9;

      break;

    case HAL_UART_BR_57600:

      UxGCR = 10;

      dmaCfg.txTick = 6;

      break;

    default:

      // HAL_UART_BR_115200

      UxGCR = 11;

      dmaCfg.txTick = 3;

      break;

  }

 

  // 8 bits/char; no parity; 1 stop bit; stop bit hi.

  if (config->flowControl)

  {

    UxUCR = UCR_FLOW | UCR_STOP;

    PxSEL |= HAL_UART_Px_CTS;

    // DMA Rx is always on (self-resetting). So flow must be controlled by the S/W polling the Rx

    // buffer level. Start by allowing flow.

    PxOUT &= ~HAL_UART_Px_RTS;

    PxDIR |=  HAL_UART_Px_RTS;

  }

  else

  {

    UxUCR = UCR_STOP;

  }

 

  dmaCfg.rxBuf[0] = *(volatile uint8 *)DMA_UDBUF;  // Clear the DMA Rx trigger.

  HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX);

  HAL_DMA_ARM_CH(HAL_DMA_CH_RX);

  osal_memset(dmaCfg.rxBuf, (DMA_PAD ^ 0xFF), HAL_UART_DMA_RX_MAX*2);

 

  UxCSR |= CSR_RE;

  

  // Initialize that TX DMA is not pending

  dmaCfg.txDMAPending = FALSE;

  dmaCfg.txShdwValid = FALSE;

}

Zigbee协议栈中,TI采用的方法是将串口和DMA结合起来使用

该函数有个halUARTCfg_t类型的参数,定义如下:

 

typedef struct

{

  bool                configured;

  uint8               baudRate;

  bool                flowControl;

  uint16              flowControlThreshold;

  uint8               idleTimeout;

  halUARTBufControl_t rx;

  halUARTBufControl_t tx;

  bool                intEnable;

  uint32              rxChRvdTime;

  halUARTCBack_t      callBackFunc;

}halUARTCfg_t;

 

typedef void (*halUARTCBack_t) (uint8 port, uint8 event);

 

HalUARTOpenDMA()函数中对串口波特率进行了初始化,同时对DMA接收缓冲区进行了初始化

 

Zigbee协议栈中,开辟了DMA发送缓冲区和接收缓冲区:

用户通过串口向串口发送数据时,数据首先存放在DMA接收缓冲区中,然后用户调用HalUARTRead()函数进行读取,实际上是读取DMA缓冲区中的数据,HalUARTRead()函数原型如下:

 

uint16 HalUARTRead(uint8 port, uint8 *buf, uint16 len)

{

  (void)port;

  (void)buf;

  (void)len;

 

#if (HAL_UART_DMA == 1)

  if (port == HAL_UART_PORT_0)  return HalUARTReadDMA(buf, len);

#endif

#if (HAL_UART_DMA == 2)

  if (port == HAL_UART_PORT_1)  return HalUARTReadDMA(buf, len);

#endif

#if (HAL_UART_ISR == 1)

  if (port == HAL_UART_PORT_0)  return HalUARTReadISR(buf, len);

#endif

#if (HAL_UART_ISR == 2)

  if (port == HAL_UART_PORT_1)  return HalUARTReadISR(buf, len);

#endif

 

#if HAL_UART_USB

  return HalUARTRx(buf, len);

#else

  return 0;

#endif

}

当用户调用HalUARTWrite()函数发送数据时,实际上是将数据写入DMA发送缓冲区,然后DMA自动将发送缓冲区中的数据通过串口发送给PC

 

uint16 HalUARTWrite(uint8 port, uint8 *buf, uint16 len)

{

  (void)port;

  (void)buf;

  (void)len;

 

#if (HAL_UART_DMA == 1)

  if (port == HAL_UART_PORT_0)  return HalUARTWriteDMA(buf, len);

#endif

#if (HAL_UART_DMA == 2)

  if (port == HAL_UART_PORT_1)  return HalUARTWriteDMA(buf, len);

#endif

#if (HAL_UART_ISR == 1)

  if (port == HAL_UART_PORT_0)  return HalUARTWriteISR(buf, len);

#endif

#if (HAL_UART_ISR == 2)

  if (port == HAL_UART_PORT_1)  return HalUARTWriteISR(buf, len);

#endif

 

#if HAL_UART_USB

  HalUARTTx(buf, len);

  return len;

#else

  return 0;

#endif

}

 

 PC与Zigbee任意字符串传输实验

#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include "DebugTrace.h"
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"
#include "OSAL_Nv.h"
#include "GenericApp.h"
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS]=
{
 GENERICAPP_CLUSTERID

};

const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{
 GENERICAPP_ENDPOINT,
 GENERICAPP_PROFID,
 GENERICAPP_DEVICEID,
 GENERICAPP_DEVICE_VERSION,
 GENERICAPP_FLAGS,
 GENERICAPP_MAX_CLUSTERS,
 (cId_t *)GenericApp_ClusterList,
 0,
 (cId_t *)NULL
 
  
};

static uint8 SerialApp_TxLen;
endPointDesc_t GenericApp_epDesc;
byte GenericApp_TaskID;
byte GenericApp_TransID;
static void rxCB(uint8 port,uint8 event);


 void GenericApp_Init(uint8 task_id)
 {
 halUARTCfg_t uartConfig;
 GenericApp_TaskID = task_id;
 GenericApp_TransID = 0;


 GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
 GenericApp_epDesc.task_id  = &GenericApp_TaskID;
 GenericApp_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;
 GenericApp_epDesc.latencyReq = noLatencyReqs;

 afRegister(&GenericApp_epDesc);

 uartConfig.configured = TRUE;
 uartConfig.baudRate = HAL_UART_BR_115200;
 uartConfig.flowControl = FALSE;
 uartConfig.flowControlThreshold = 64;
 uartConfig.rx.maxBufSize = 128;
 uartConfig.tx.maxBufSize = 128;
 uartConfig.idleTimeout =6;
 uartConfig.intEnable = TRUE;
 uartConfig.callBackFunc = rxCB;
 HalUARTOpen(0,&uartConfig);
 


 }

 UINT16 GenericApp_ProcessEvent(byte task_id,UINT16 events)
  {



 }

 static void rxCB(uint8 port,uint8 event)
  {

 unsigned char Uartbuf[80];
 if((event & (HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT))&&
#if SERIAL_APP_LOOPBACK
 (SerialApp_TxLen < SERIAL_APP_TX_MAX))
#else
 !SerialApp_TxLen)

#endif

 {
  SerialApp_TxLen = HalUARTRead(0,Uartbuf,80);
  if(SerialApp_TxLen)
   {

   HalUARTWrite(0,Uartbuf,SerialApp_TxLen);
   SerialApp_TxLen = 0;
  }

 }
 }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值