【记录】STM32串口测试

测试环境

正点原子战舰STM32F767

STM32串口

中断收发

为了验证硬件的正确性,最简单的方法是接收串口工具的数据,然后将接收到的数据发送

【记录】STM32串口测试_第1张图片
【记录】STM32串口测试_第2张图片
【记录】STM32串口测试_第3张图片

STM32串口-接收定长数据



uint8_t g_u8SndBuf[UART_LEN] = "USART1 Send test\n\r";
uint8_t g_u8RcvBuf[UART_LEN] = {0};

void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  
  //for test
  HAL_UART_Transmit_IT(&huart1, g_u8SndBuf, sizeof(g_u8SndBuf));
  HAL_UART_Receive_IT(&huart1, g_u8RcvBuf, 10); //to receive fixed lenght of data
}


void USART1_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart1);
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		HAL_UART_Transmit_IT(&huart1, g_u8RcvBuf, sizeof(g_u8RcvBuf));
		HAL_UART_Receive_IT(&huart1, g_u8RcvBuf, 10);  //enable receive interrupt again
	}
}

【记录】STM32串口测试_第4张图片

STM32串口-接收不定长数据

1. 定时接收

2. 固定结束符

当接收到固定字符(如:0x0D),认为接收完成



#define UART_LEN	128

UART_HandleTypeDef huart1;

uint8_t *s_pbSnd = NULL;
uint8_t *s_pbRcv = NULL;
uint16_t s_wSndCnt = 0;
uint16_t s_wSndIndex = 0;
uint16_t s_wRcvIndex = 0;
uint8_t s_bRcvDone = 0;

void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  
  /* Enable the UART RXNE interrupt*/
  SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);
}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */

  /* USER CODE END USART1_MspInit 0 */
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */

  /* USER CODE END USART1_MspInit 1 */
  }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspDeInit 0 */

  /* USER CODE END USART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();
  
    /**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

    /* USART1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspDeInit 1 */

  /* USER CODE END USART1_MspDeInit 1 */
  }
} 

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
	uint32_t isrflags = READ_REG(huart1.Instance->ISR);
	uint32_t cr1its = READ_REG(huart1.Instance->CR1);
	uint32_t cr2its = READ_REG(huart1.Instance->CR2);
	uint8_t u8RcvChar = 0;

	/* UART in mode Receiver ---------------------------------------------------*/
	if ((isrflags & USART_ISR_RXNE) && (cr1its & USART_CR1_RXNEIE))
	{
		u8RcvChar = (uint8_t)(huart1.Instance->RDR & 0xFF);
		s_pbRcv[s_wRcvIndex++] = u8RcvChar;
		if (u8RcvChar == 0x0D)
		{
			s_bRcvDone = 1;
			
			//isr_evt_set(RECV_READY_EVT)
		}
	}
	else
	{
		/* UART in mode Transmitter ------------------------------------------------*/
		if((isrflags & USART_ISR_TXE) && (cr1its & USART_CR1_TXEIE))
		{
			if (s_wSndCnt == 0)
			{
				/* Disable the UART Transmit Data Register Empty Interrupt */
				CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TXEIE);

				/* Clear the UART Transmit Complete Interrupt Flag */
				__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
				/* Enable the UART Transmit Complete Interrupt */
				SET_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
			}
			else
			{
				huart1.Instance->TDR = s_pbSnd[s_wSndIndex++];
				s_wSndCnt--;
			}
		}
	
		/* UART in mode Transmitter (transmission end) -----------------------------*/
		if((isrflags & USART_ISR_TC) && (cr1its & USART_CR1_TCIE))
		{
			/* Clear the UART Transmit Complete Interrupt Flag */
			__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
			/* Disable the UART Transmit Complete Interrupt */
			CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
			
			//isr_evt_set(SEND_READY_EVT)
		}
	}
}

int8_t USART1_Snd(uint8_t* pbSndBuf, uint16_t wSndCnt)
{
	int8_t ret = 0;
	
	if ((pbSndBuf == NULL) && (wSndCnt == 0))
	{
		return -1;
	}
	
	s_pbSnd = pbSndBuf;
	s_wSndCnt = wSndCnt;
	s_wSndIndex = 0;
	
	/* Enable the UART Transmit Data Register Empty Interrupt */
	SET_BIT(huart1.Instance->CR1, USART_CR1_TXEIE);
	
	return ret;
}

int8_t USART1_Rcv(uint8_t* pbRcvBuf, uint16_t *pwRcvCnt, uint16_t wResponseTimeout)
{
	int8_t ret = 0;
	
	s_bRcvDone = 0;
	s_wRcvIndex = 0;
	
	s_pbRcv = pbRcvBuf;
	
	//os_evt_wait_or(RECV_READY_EVT,WAITFOREVER);
	
	*pwRcvCnt = s_wRcvIndex;
	
	return ret;
}

void USART1_Test(void)
{
	static uint8_t s_bInit = 0;
	static uint8_t s_bSndBuf[UART_LEN] = "USART1 Send test!!!\n\r";
	static uint8_t s_bRcvBuf[UART_LEN] = {0};
	uint16_t wRcvCnt = 0;
	
	if (s_bInit == 0)
	{
		USART1_Rcv(s_bRcvBuf, &wRcvCnt, 1000);
		s_bInit = 1;
	}
	
	if (s_bRcvDone == 1)
	{
		memcpy(s_bSndBuf, s_bRcvBuf, s_wRcvIndex);
		USART1_Snd(s_bSndBuf, s_wRcvIndex);
		
		USART1_Rcv(s_bRcvBuf, &wRcvCnt, 1000);
		
		HAL_Delay(1);
	}
}


3. Idle中断

在这里插入图片描述

当检测到空闲状态时,认为接收完成


void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  
  /* Enable the UART RXNE interrupt*/
  SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);
  /* Enable IDLE interrupt, as the end of frame*/
  SET_BIT(huart1.Instance->CR1, USART_CR1_IDLEIE);
}


void USART1_IRQHandler(void)
{
	uint32_t isrflags = READ_REG(huart1.Instance->ISR);
	uint32_t cr1its = READ_REG(huart1.Instance->CR1);
	uint32_t cr2its = READ_REG(huart1.Instance->CR2);
	uint8_t u8RcvChar = 0;

	/* UART in mode Receiver ---------------------------------------------------*/
	if ((isrflags & USART_ISR_RXNE) && (cr1its & USART_CR1_RXNEIE))
	{
		u8RcvChar = (uint8_t)(huart1.Instance->RDR & 0xFF);
		s_pbRcv[s_wRcvIndex++] = u8RcvChar;
	}
	/* UART IDLE Interrupt ---------------------------------------------------*/
	else if (((isrflags & USART_ISR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET))
    {
		/* Clear the UART Idle Interrupt Flag */
		__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_IDLEF);
		s_bRcvDone = 1;
		//isr_evt_set(RECV_READY_EVT)
    }
	else
	{
		/* UART in mode Transmitter ------------------------------------------------*/
		if((isrflags & USART_ISR_TXE) && (cr1its & USART_CR1_TXEIE))
		{
			if (s_wSndCnt == 0)
			{
				/* Disable the UART Transmit Data Register Empty Interrupt */
				CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TXEIE);

				/* Clear the UART Transmit Complete Interrupt Flag */
				__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
				/* Enable the UART Transmit Complete Interrupt */
				SET_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
			}
			else
			{
				huart1.Instance->TDR = s_pbSnd[s_wSndIndex++];
				s_wSndCnt--;
			}
		}
	
		/* UART in mode Transmitter (transmission end) -----------------------------*/
		if((isrflags & USART_ISR_TC) && (cr1its & USART_CR1_TCIE))
		{
			/* Clear the UART Transmit Complete Interrupt Flag */
			__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
			/* Disable the UART Transmit Complete Interrupt */
			CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
			
			//isr_evt_set(SEND_READY_EVT)
		}
	}
}


4. RTO中断

接收器超时中断(UART receiver timeout interrupt),当RX线路在RTOR设定的超时时间内,持续处于空闲状态,表示接收完成。RTOR以bit为单位

int8_t USART1_Rcv(uint8_t* pbRcvBuf, uint16_t *pwRcvCnt, uint16_t wResponseTimeout)
{
	int8_t ret = 0;
	
	s_bRcvDone = 0;
	s_wRcvIndex = 0;
	
	s_pbRcv = pbRcvBuf;
	
	/* Enable the UART RXNE interrupt*/
	SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);

	// set character time out = 28bit = 2,5 character with 11bit frame format
	WRITE_REG(huart1.Instance->RTOR,28);
	/* Clear the UART Receiver Timeout Interrupt Flag */
	__HAL_UART_CLEAR_IT(&huart1, USART_ICR_RTOCF);
	/* Enable the UART Receiver Timeout Interrupt */
	SET_BIT(huart1.Instance->CR1, USART_CR1_RTOIE);
	SET_BIT(huart1.Instance->CR2, USART_CR2_RTOEN);
	
	//os_evt_wait_or(RECV_READY_EVT,WAITFOREVER);
	
	*pwRcvCnt = s_wRcvIndex;
	
	return ret;
}


void USART1_IRQHandler(void)
{
	uint32_t isrflags = READ_REG(huart1.Instance->ISR);
	uint32_t cr1its = READ_REG(huart1.Instance->CR1);
	uint32_t cr2its = READ_REG(huart1.Instance->CR2);
	uint8_t u8RcvChar = 0;

	/* UART in mode Receiver ---------------------------------------------------*/
	if ((isrflags & USART_ISR_RXNE) && (cr1its & USART_CR1_RXNEIE))
	{
		u8RcvChar = (uint8_t)(huart1.Instance->RDR & 0xFF);
		s_pbRcv[s_wRcvIndex++] = u8RcvChar;
	}
	/* UART Receiver Timeout Interrupt -----------------------------------------*/
	else if ((isrflags & USART_ISR_RTOF) && (cr2its & USART_CR2_RTOEN))
    {
		/* Clear the UART Receiver Timeout Interrupt Flag */
		__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_OREF);
		/* Disable the UART Receiver Timeout Interrupt */
		CLEAR_BIT(huart1.Instance->CR1, USART_CR1_RTOIE);
		CLEAR_BIT(huart1.Instance->CR2, USART_CR2_RTOEN);
		
		s_bRcvDone = 1;
		//isr_evt_set(RECV_READY_EVT)
    }
	else
	{
		/* UART in mode Transmitter ---------------------------------------------*/
		if((isrflags & USART_ISR_TXE) && (cr1its & USART_CR1_TXEIE))
		{
			if (s_wSndCnt == 0)
			{
				/* Disable the UART Transmit Data Register Empty Interrupt */
				CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TXEIE);

				/* Clear the UART Transmit Complete Interrupt Flag */
				__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
				/* Enable the UART Transmit Complete Interrupt */
				SET_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
			}
			else
			{
				huart1.Instance->TDR = s_pbSnd[s_wSndIndex++];
				s_wSndCnt--;
			}
		}
	
		/* UART in mode Transmitter (transmission end) -----------------------------*/
		if((isrflags & USART_ISR_TC) && (cr1its & USART_CR1_TCIE))
		{
			/* Clear the UART Transmit Complete Interrupt Flag */
			__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
			/* Disable the UART Transmit Complete Interrupt */
			CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
			
			//isr_evt_set(SEND_READY_EVT)
		}
	}
}

参考资料

STM32使用HAL库实现串口通讯——理论讲解
STM32CubeMX系列教程5:串行通信(USART)
STM32串口接收不定长数据原理与源程序***
适用于所有STM32单片机的串口不定长接收***
STM32之串口DMA接收不定长数据***
如何判断串口接收完成一帧数据***
STM32 Uart 接收不定长数据***

你可能感兴趣的:(STM32F4,Cortex-M4)