HAL库的学习——串口中断接收不到数据或只能接收一两个字符

一、操作步骤

       使用SMT32CubeMx配置指定引脚为UART后在右侧界面点击Connectivity->USART2->Mode选择异步模式Asynchronous,查看串口的基础配置-Parameter Settings,保持默认不变。

HAL库的学习——串口中断接收不到数据或只能接收一两个字符_第1张图片

        选择NVIC Settings点击Enabled使能全局中断。

HAL库的学习——串口中断接收不到数据或只能接收一两个字符_第2张图片

       这样整个串口配置就完成了。

二、代码实现

       在自动生成代码里点开MX_USART2_UART_Init(void)函数并在最后面加入此句HAL_UART_Receive_IT(&huart2,&mUART2.TEMP,1);使用变量mUART2.TEMP接收数据,每次接收一个字节。

static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */
  HAL_UART_Receive_IT(&huart2,&mUART2.TEMP,RECLEN);
  /* USER CODE END USART2_Init 2 */

}

       在写中断回调函数,void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)(系统内部会自动映射到这个函数,相当于重写这个函数给系统调用)。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART2)
	{
	  if(mUART2.TEMP == '!' && mUART2.FLG == 0)
		{
			mUART2.FLG = 1;
			mUART2.Uart_Len = 0;
		}
		if(mUART2.FLG)
		{			
			mUART2.BUF[mUART2.Uart_Len] = mUART2.TEMP;
			++mUART2.Uart_Len;
		}
		if(mUART2.Uart_Len >6 && mUART2.BUF[mUART2.Uart_Len - 1] == 0x0a)
		{		
			mUART2.LEN = mUART2.Uart_Len;
			mUART2.Uart_Len = 0;
			mUART2.FLG = 0;
			mUART2.RX_FLG = 1;
		}
	    while(HAL_UART_Receive_IT(&huart2,&mUART2.TEMP,RECLEN) != HAL_OK);
	}
}

        这里要接收的数据是以 '!' 开头,以0D 0A结尾的数据格式。这时候使用串口助手发送相应的数据格式,使用printf打印(需要映射,编写如下代码即可调用printf函数),发现没有进入串口中断或出现偶尔进两、三次的现象。

/***************printf映射函数的实现*****************************/
#include 


#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1 , 0xffff);
    return ch;
}
/***************printf映射函数的实现*****************************/



三、原因

       主要原因是时钟的问题,发现改成38400之后,默认的时钟配置是支持的,因此重新配置时钟,使用如下配置:

HAL库的学习——串口中断接收不到数据或只能接收一两个字符_第3张图片

         默认配置是2.095M,不支持115200波特率。

四、结论

        配置波特率时,注意时钟的配置,当时钟不够相应的波特率即会出现一些异常。

你可能感兴趣的:(STM32)