为什么使用HAL_UART_Receive不能持续接收到数据?

我是接收GPS模组的数据,可以确认GPS模组那边是一直有数据输出的。我的UART初始化函数如下:

static void MX_LPUART1_UART_Init(void)

{

  Lpuart1.Instance = LPUART1;

  Lpuart1.Init.BaudRate = 9600;

  Lpuart1.Init.WordLength = UART_WORDLENGTH_8B;

  Lpuart1.Init.StopBits = UART_STOPBITS_1;

  Lpuart1.Init.Parity = UART_PARITY_NONE;

  Lpuart1.Init.Mode = UART_MODE_TX_RX;

  Lpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;

  Lpuart1.Init.OverSampling = UART_OVERSAMPLING_16;

  Lpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

  Lpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

  if (HAL_UART_Init(&Lpuart1) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

}

然后就循环调用下面的语句接收,结果总是只能接收一次,之后就一直返回Timeout,应该RXNE一直为零,不知为何?请高手指教,多谢!

HAL_UART_Receive(&Lpuart1, DataBuf, DataLen, 10000);

已邀请:

江浩生

赞同来自:

接受完一次,中断后调用的函数会把RXNEIE清零,关掉中断。要重新初始化

shine2018

赞同来自:

多谢,重新初始化是要调哪些函数,从HAL_UART_Init全部执行一遍?

还是说__HAL_UART_ENABLE就可以了?

我看RXNEIE是在HAL_UART_Receive_IT设置的,我又不需要中断传输,不能调啊

江浩生

赞同来自:

抱歉,你使用的是Polling方式吧?我用STM32L053R8 NUCLEO板子,用其固件库的例程ComPolling例子,串口模拟GPS数据发送不断往USART1发送数据,并不会出现你说的会返回timeout,除非停止发送。1531466259360141.jpg

而且就第一次可以的情况看,RXNE的置1和清零的情况是正常的。会不会是其他问题。如果可以贴上更完整的HAL_UART_Receive(&Lpuart1, DataBuf, DataLen, 10000);程序源码来分析会更好。

shine2018

赞同来自:

非常感谢您的帮助,我考虑到效率问题,还成了DMA方式,代码如下。结果总是无法收到任何数据,不知道问题出在哪里,帮忙看看~~

int main(void)

{

   MX_GPIO_Init();

   MX_DMA_Init();

   MX_LPUART1_UART_Init();

   HAL_UART_Receive_DMA(&Lpuart1,DataBuf,32);

}

static void MX_LPUART1_UART_Init(void)

{

  Lpuart1.Instance = LPUART1;

  Lpuart1.Init.BaudRate = 9600;

  Lpuart1.Init.WordLength = UART_WORDLENGTH_8B;

  Lpuart1.Init.StopBits = UART_STOPBITS_1;

  Lpuart1.Init.Parity = UART_PARITY_NONE;

  Lpuart1.Init.Mode = UART_MODE_TX_RX;

  Lpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;

  Lpuart1.Init.OverSampling = UART_OVERSAMPLING_16;

  Lpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

  Lpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

  if (HAL_UART_Init(&Lpuart1) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

}


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

    printf("enter rx callback\r\n");

    if(huart->Instance == LPUART1)

   {

HAL_UART_Receive_DMA(&Lpuart1,DataBuf,512);

   }

}


static void MX_GPIO_Init(void)

{


  GPIO_InitTypeDef GPIO_InitStruct;


  /* GPIO Ports Clock Enable */

  __HAL_RCC_GPIOC_CLK_ENABLE();

  __HAL_RCC_GPIOH_CLK_ENABLE();

  __HAL_RCC_GPIOA_CLK_ENABLE();


  /*Configure GPIO pin Output Level */

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);


  /*Configure GPIO pin : PA5 */

  GPIO_InitStruct.Pin = GPIO_PIN_5;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

}


void HAL_UART_MspInit(UART_HandleTypeDef* huart)

{


  GPIO_InitTypeDef GPIO_InitStruct;

  if(huart->Instance==USART2)

  {

  /* USER CODE BEGIN USART2_MspInit 0 */


  /* USER CODE END USART2_MspInit 0 */

    /* Peripheral clock enable */

    __HAL_RCC_USART2_CLK_ENABLE();

  

    /**USART2 GPIO Configuration    

    PA2     ------> USART2_TX

    PA3     ------> USART2_RX 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


  /* USER CODE BEGIN USART2_MspInit 1 */


  /* USER CODE END USART2_MspInit 1 */

  } else if(huart->Instance==LPUART1)

  {

  /* USER CODE BEGIN LPUART1_MspInit 0 */


  /* USER CODE END LPUART1_MspInit 0 */

    /* Peripheral clock enable */

    __HAL_RCC_LPUART1_CLK_ENABLE();

  

    /**USART2 GPIO Configuration    

    PA2     ------> LPUART1_TX

    PA3     ------> LPUART1_RX 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF0_LPUART1;

    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

hdma_lpuart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;

hdma_lpuart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_lpuart1_rx.Init.MemInc = DMA_MINC_ENABLE;

hdma_lpuart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_lpuart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

hdma_lpuart1_rx.Init.Mode = DMA_NORMAL;

hdma_lpuart1_rx.Init.Priority = DMA_PRIORITY_LOW;

hdma_lpuart1_rx.Init.Request = DMA_REQUEST_5;

hdma_lpuart1_rx.Instance = DMA1_Channel3;

if (HAL_DMA_Init(&hdma_lpuart1_rx) != HAL_OK)

    {

      _Error_Handler(__FILE__, __LINE__);

    }

__HAL_LINKDMA(huart, hdmarx, hdma_lpuart1_rx);

__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);

HAL_NVIC_SetPriority(LPUART1_IRQn, 0, 1);

    HAL_NVIC_EnableIRQ(LPUART1_IRQn);

printf("LPUART1 init\r\n");


  /* USER CODE BEGIN LPUART1_MspInit 1 */


  /* USER CODE END LPUART1_MspInit 1 */

  }


}


void RNG_LPUART1_IRQHandler(void)

{

UART_IDLE_Callback(&Lpuart1);

HAL_UART_IRQHandler(&Lpuart1);

}


void DMA1_Channel2_3_IRQHandler(void)

{

HAL_DMA_IRQHandler(&hdma_lpuart1_rx);

}


江浩生

赞同来自:

说些无关的东西

  1. 我也是刚接触STM32串口收发不就,DMA方式不熟,抱歉。


  2. 功能你是自己全部重新写的吗?有没有成功的实现功能,就是相应的收发功能,集成到接收GPS数据之前。如果没有成功就集成进来,自然有很多问题。而且之前的没有通过DMA的都没有实现,添加新的模块也会有问题,之前我也尝试过使用DMA,但是因为还没有完全理解而增加了问题,所以最近都是用IT中断来实现。

  3. 粗略观察你的主函数,竟然初始化完就结束了一般至少在最后面加一个死循环吧

  4. 其实你发的代码还有一些地方不清楚的,比如printf是输出到串口的重新定义的函数吗?

  5. 一天下来,才解决了用IT方式,实现单个字节的收发。如果不是自己的代码,找起来更是难上加难,因此如果能够做当清晰地提问,提供必要的内容,会好得多。

  6. 拙见


chaojie

赞同来自:

试试把cubemx的串口中断中断勾上

要回复问题请先登录注册