微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > CC2541串口记录

CC2541串口记录

时间:10-02 整理:3721RD 点击:

串口什么时候进回调函数?

答:

1)正常串口端无发送、无接收时,是不会进回调函数的。如果这种情况会进回调函数,TX、RX端外接上拉电阻稳定电平。

2)如果接收端有数据,立马就会进回调。事件是“接收超时事件”。

3)2541发送端发送完数据,会进回调函数。事件是“发送缓冲区空事件”。


这里的“接收超时事件”是通过轮询DMA中是否有数据,有数据则设置事件,然后跳转到串口回调函数,具体内容如下:

首先从初始化看起
void hal_Uart_Init(void)
{
  NPI_InitTransport(simpleBLE_NpiSerialCallback);  //simpleBLE_NpiSerialCallback 这就是串口回调函数
  NPI_WriteTransport("\nUart_Init\r\n", 12);  
}

void NPI_InitTransport( npiCBack_t npiCBack )
{
  halUARTCfg_t uartConfig;

  // configure UART
  uartConfig.configured           = TRUE;
  uartConfig.baudRate             = NPI_UART_BR;              //波特率
  uartConfig.flowControl          = NPI_UART_FC;              //流控制
  uartConfig.flowControlThreshold = NPI_UART_FC_THRESHOLD;    //流控制阀值,当开启flowControl时,该设置有效
  uartConfig.rx.maxBufSize        = NPI_UART_RX_BUF_SIZE;     //接收缓冲区大小
  uartConfig.tx.maxBufSize        = NPI_UART_TX_BUF_SIZE;     //发送缓冲区大小
  uartConfig.idleTimeout          = NPI_UART_IDLE_TIMEOUT;
  uartConfig.intEnable            = NPI_UART_INT_ENABLE;      //是否开启中断
  uartConfig.callBackFunc         = (halUARTCBack_t)npiCBack; //接收回调函数      在这里uartConfig.callBackFunc指向它

  // start UART
  // Note: Assumes no issue opening UART port.
  (void)HalUARTOpen( NPI_UART_PORT, &uartConfig );

  return;
}

uint8 HalUARTOpen(uint8 port, halUARTCfg_t *config)
{
#if (HAL_UART_DMA == 1)
  if (port == HAL_UART_PORT_0)  HalUARTOpenDMA(config);

}

static void HalUARTOpenDMA(halUARTCfg_t *config)
{
  dmaCfg.uartCB = config->callBackFunc; //将串口回调函数地址给dmaCfg.uartCB全局变量
.
}
由上面几个函数知道,最终回调函数地址给到了dmaCfg.uartCB全局变量,然后在下面函数中进行跳转
static void HalUARTPollDMA(void)
{
  uint8 evt = 0;
  uint16 cnt;

#if DMA_PM
  PxIEN &= ~DMA_RDYIn_BIT;  // Clear to not race with DMA_RDY_IN ISR.
  {
    if (dmaRdyIsr || HAL_UART_DMA_RDY_IN() || HalUARTBusyDMA())
    {
      // Master may have timed-out the SRDY asserted state & may need a new edge.
#if HAL_UART_TX_BY_ISR
      if (!HAL_UART_DMA_RDY_IN() && (dmaCfg.txHead != dmaCfg.txTail))
#else
      if (!HAL_UART_DMA_RDY_IN() && ((dmaCfg.txIdx[0] != 0) || (dmaCfg.txIdx[1] != 0)))
#endif
      {
        HAL_UART_DMA_CLR_RDY_OUT();
      }
      dmaRdyIsr = 0;

      if (dmaRdyDly == 0)
      {
        (void)osal_set_event(Hal_TaskID, HAL_PWRMGR_HOLD_EVENT);
      }

      if ((dmaRdyDly = ST0) == 0)  // Reserve zero to signify that the delay expired.
      {
        dmaRdyDly = 0xFF;
      }
      HAL_UART_DMA_SET_RDY_OUT();
    }
    else if ((dmaRdyDly != 0) && (!DMA_PM_DLY || ((uint8)(ST0 - dmaRdyDly) > DMA_PM_DLY)))
    {
      dmaRdyDly = 0;
      (void)osal_set_event(Hal_TaskID, HAL_PWRMGR_CONSERVE_EVENT);
    }
  }
  PxIEN |= DMA_RDYIn_BIT;
#endif

#if !HAL_UART_TX_BY_ISR
  HalUARTPollTxTrigDMA(); //
#endif

  if (!HAL_UART_DMA_NEW_RX_BYTE(dmaCfg.rxHead))
  {
    if (HAL_UART_DMA_NEW_RX_BYTE(uartRxBug))
    {
      do {
        HAL_UART_RX_IDX_T_INCR(dmaCfg.rxHead);
      } while (!HAL_UART_DMA_NEW_RX_BYTE(dmaCfg.rxHead));

      uartRxBug = dmaCfg.rxHead;
      dmaCfg.rxTail = dmaCfg.rxHead;
    }
    HAL_UART_RX_IDX_T_INCR(uartRxBug);
  }

  cnt = HalUARTRxAvailDMA();  // Wait to call until after the above DMA Rx bug work-around.

#if HAL_UART_DMA_IDLE
  if (dmaCfg.rxTick)
  {
    // Use the LSB of the sleep timer (ST0 must be read first anyway) to measure the Rx timeout.
    if ((ST0 - dmaCfg.rxTick) > HAL_UART_DMA_IDLE)
    {
      dmaCfg.rxTick = 0;
      evt = HAL_UART_RX_TIMEOUT;
    }
  }
  else if (cnt != 0)
  {
    if ((dmaCfg.rxTick = ST0) == 0)  // Zero signifies that the Rx timeout is not running.
    {
      dmaCfg.rxTick = 0xFF;
    }
  }
#else
  if (cnt != 0)
  {
    evt = HAL_UART_RX_TIMEOUT;  //设置为接收超时事件
  }
#endif

  if (cnt >= HAL_UART_DMA_FULL)
  {
    evt |= HAL_UART_RX_FULL;//接收为空事件?
  }
  else if (cnt >= HAL_UART_DMA_HIGH)
  {
    evt |= HAL_UART_RX_ABOUT_FULL;

    if (!DMA_PM && (UxUCR & UCR_FLOW))
    {
      HAL_UART_DMA_CLR_RDY_OUT();  // Disable Rx flow.
    }
  }

  if (dmaCfg.txMT)
  {
    dmaCfg.txMT = FALSE;
    evt |= HAL_UART_TX_EMPTY;
  }

  if ((evt != 0) && (dmaCfg.uartCB != NULL))
  {
    dmaCfg.uartCB(HAL_UART_DMA-1, evt);         //跳转到串口回调函数
  }

  if (DMA_PM && (dmaRdyDly == 0) && !HalUARTBusyDMA())
  {
    HAL_UART_DMA_CLR_RDY_OUT();
  }
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top