欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【记录】STM32串口测试

程序员文章站 2024-02-22 18:40:46
...

测试环境

正点原子战舰STM32F767

STM32串口

中断收发

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

【记录】STM32串口测试
【记录】STM32串口测试
【记录】STM32串口测试

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串口测试

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中断

【记录】STM32串口测试

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


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