自己实现STM32串口中断接收服务函数

1. 初始化函数不变

void MX_USART6_UART_Init(void)
{

  huart6.Instance = USART6;
  huart6.Init.BaudRate = 115200;
  huart6.Init.WordLength = UART_WORDLENGTH_8B;
  huart6.Init.StopBits = UART_STOPBITS_1;
  huart6.Init.Parity = UART_PARITY_NONE;
  huart6.Init.Mode = UART_MODE_TX_RX;
  huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart6.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart6) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

2. MspInit函数中设置中断优先级,开启中断

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(uartHandle->Instance==USART6)
  {
  /* USER CODE BEGIN USART6_MspInit 0 */

  /* USER CODE END USART6_MspInit 0 */
    /* USART6 clock enable */
    __HAL_RCC_USART6_CLK_ENABLE();
  
    /**USART6 GPIO Configuration    
    PC6     ------> USART6_TX
    PG9     ------> USART6_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  /* USER CODE BEGIN USART6_MspInit 1 */
    /* USART6 interrupt Init */
    HAL_NVIC_SetPriority(USART6_IRQn, 6, 0);
    HAL_NVIC_EnableIRQ(USART6_IRQn);
    /* Enable the UART Data Register not empty Interrupts */
    SET_BIT(uartHandle->Instance->CR1, USART_CR1_RXNEIE);
  /* USER CODE END USART6_MspInit 1 */
  }
}

3. MspDeInit中关闭中断

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

  if(uartHandle->Instance==USART6)
  {
  /* USER CODE BEGIN USART6_MspDeInit 0 */

  /* USER CODE END USART6_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART6_CLK_DISABLE();
  
    /**USART6 GPIO Configuration    
    PC6     ------> USART6_TX
    PG9     ------> USART6_RX 
    */
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6);

    HAL_GPIO_DeInit(GPIOG, GPIO_PIN_9);

  /* USER CODE BEGIN USART6_MspDeInit 1 */
    /* USART6 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART6_IRQn);
    /* Disable the UART RXNE interrupt*/
    CLEAR_BIT(uartHandle->Instance->CR1, USART_CR1_RXNEIE);
  /* USER CODE END USART6_MspDeInit 1 */
  }
} 

4. 重写串口中断服务函数

void USART6_IRQHandler(void)
{
  uint32_t isrflags   = READ_REG(huart6.Instance->SR);
  uint32_t cr1its     = READ_REG(huart6.Instance->CR1);
  uint32_t errorflags = 0x00U;
  uint8_t dump;
  
  errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));   //检查所有错误,有错误就丢弃
  if(errorflags == RESET)
  {
    /* UART in mode Receiver -------------------------------------------------*/
    if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
    {
      Rx_Buf[0] = (uint8_t)(huart6.Instance->DR & (uint8_t)0x00FF);
    }
  }
  else
  {
    dump = (uint8_t)(huart6.Instance->DR & (uint8_t)0x00FF);    //发生错误,数据丢弃
  }
  
}

5. 测试串口各种错误

溢出错误

(RDR内容未及时读出,RDR内容将不会丢失。读USART_DR寄存器仍能得到先前的数据。USART_DR中数据有效。

噪声错误(开始信号、数据3次采样值不同)、帧错误(没接收到STOP信号),

无效数据从移位寄存器传送到USART_DR寄存器。USART_DR中数据无效。

极性错误

该错误一定要Parity = UART_PARITY_EVEN或者Parity = UART_PARITY_ODD。这样才能使能该错误。

读完SR寄存器,哪些错误标志位会都清零。

自己实现STM32串口中断接收服务函数_第1张图片

5.1 测试极性错误(PE)

以115200发送为例
自己实现STM32串口中断接收服务函数_第2张图片
先设置huart6.Init.Parity = UART_PARITY_EVEN;
再按下图设置发送“0x31”

自己实现STM32串口中断接收服务函数_第3张图片
自己实现STM32串口中断接收服务函数_第4张图片

5.2 测试帧错误(FE)

按下图设置
自己实现STM32串口中断接收服务函数_第5张图片
发送“0x31”
自己实现STM32串口中断接收服务函数_第6张图片

5.3 测试溢出错误(ORE)

连续发送“0x31 0x32”
自己实现STM32串口中断接收服务函数_第7张图片

5.4 噪声错误

暂时不测试。

你可能感兴趣的:(#,STM32)