STM32F411RE串行端口在中断模式下不工作

时间:2016-08-22 09:29:10

标签: stm32f4discovery stm32f4

控制器:STM32F411RE

我使用USART2作为基于中断的串行端口。我在stmcubemx中启用了NVIC,每当从终端中断传输数据时生成的代码就会生成,但uart状态为HAL_UART_STATE_READY。因为它将接收函数UART_Receive_IT函数并且出来了。请帮助解决这个问题,我还需要指导如何将uart作为中断模式。

代码:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{   
  if(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE))
  {  
      HAL_UART_Transmit(huart, str, 7, 0xFF);
      memset(str, '\0', sizeof(str));
  }

}                                /********* IRQ code*******/ 
  void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{


  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE);  
  /* UART parity error interrupt occurred ------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  { 
    __HAL_UART_CLEAR_PEFLAG(huart);

    huart->ErrorCode |= HAL_UART_ERROR_PE;
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  /* UART frame error interrupt occurred -------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  { 
    __HAL_UART_CLEAR_FEFLAG(huart);

    huart->ErrorCode |= HAL_UART_ERROR_FE;
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  /* UART noise error interrupt occurred -------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  { 
    __HAL_UART_CLEAR_NEFLAG(huart);

    huart->ErrorCode |= HAL_UART_ERROR_NE;
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  /* UART Over-Run interrupt occurred ----------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  { 
    __HAL_UART_CLEAR_OREFLAG(huart);

    huart->ErrorCode |= HAL_UART_ERROR_ORE;
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
  if(tmp2 == 0x32)
    tmp2=0x32;
  /* UART in mode Receiver ---------------------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  {         
    UART_Receive_IT(huart);
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE);
  /* UART in mode Transmitter ------------------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  {
    UART_Transmit_IT(huart);
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TC);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC);
  /* UART in mode Transmitter end --------------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  {
    UART_EndTransmit_IT(huart);
  }

  if(huart->ErrorCode != HAL_UART_ERROR_NONE)
  {
    /* Set the UART state ready to be able to start again the process */
    huart->State = HAL_UART_STATE_READY;

    HAL_UART_ErrorCallback(huart);
  }  
}                      
/************receive code *********/   
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
  uint16_t* tmp;
  uint32_t tmp1 = 0;

  tmp1 = huart->State; 
  if((tmp1 == HAL_UART_STATE_BUSY_RX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX))
  {
    if(huart->Init.WordLength == UART_WORDLENGTH_9B)
    {
      tmp = (uint16_t*) huart->pRxBuffPtr;
      if(huart->Init.Parity == UART_PARITY_NONE)
      {
        *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
        huart->pRxBuffPtr += 2;
      }
      else
      {
        *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
        huart->pRxBuffPtr += 1;
      }
    }
    else
    {
      if(huart->Init.Parity == UART_PARITY_NONE)
      {
        *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
      }
      else
      {
        *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
      }
    }

    if(--huart->RxXferCount == 0)
    {
      __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);

      /* Check if a transmit process is ongoing or not */
      if(huart->State == HAL_UART_STATE_BUSY_TX_RX) 
      {
        huart->State = HAL_UART_STATE_BUSY_TX;
      }
      else
      {
        /* Disable the UART Parity Error Interrupt */
        __HAL_UART_DISABLE_IT(huart, UART_IT_PE);

        /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
        __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);

        huart->State = HAL_UART_STATE_READY;
      }
      HAL_UART_RxCpltCallback(huart);

      return HAL_OK;
    }
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY; 
  }
} 

2 个答案:

答案 0 :(得分:0)

我认为您的代码中存在一些问题。 HAL的工作方式是让您更轻松,这样您就不需要检查中断标志等等。 在中断处理程序中,实际检查UART_IT_RXNE位,但当HAL从USART RX寄存器读取字节时,该位已自动清零。所以删除该行:

if(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE)

str似乎是一个字符数组,我认为你没有使用memset,正确的方法是:

#define LEN 7
char str[LEN];
memset(str, '\0', LEN);

我知道你想要在到达RX中断处理程序时发送一个字符串,但我不确定你是如何调用HAL_UART_Receive_IT函数的。 我使用它的方式如下:

volatile bool char_received = false;
volatile char rx_char;

int main(void)
{
    //All your hardware init here

    //Receive 1 character in interrupt mode
    HAL_UART_Receive_IT(&huart, &rx_char, 1);

    while(1)
    {
        if (rx_char == true)
        {
            rx_char = false;

            if (rx_char == 's')
            {
                HAL_UART_Transmit(&huart, "Hello", 5, 100);
            }

            HAL_UART_Receive_IT(&huart, &rx_char, 1);
         }
     }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    rx_char = true;
}

在上面的代码中,我发送了" Hello"如果我收到字符串'在中断模式下。请注意,我在中断处理程序中没有做太多,只需设置一个标志。另请注意,您需要再次拨打电话HAL_UART_Receive_IT

答案 1 :(得分:-1)

  void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{


  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE);  
  /* UART parity error interrupt occurred ------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  { 
    __HAL_UART_CLEAR_PEFLAG(huart);

    huart->ErrorCode |= HAL_UART_ERROR_PE;
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  /* UART frame error interrupt occurred -------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  { 
    __HAL_UART_CLEAR_FEFLAG(huart);

    huart->ErrorCode |= HAL_UART_ERROR_FE;
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  /* UART noise error interrupt occurred -------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  { 
    __HAL_UART_CLEAR_NEFLAG(huart);

    huart->ErrorCode |= HAL_UART_ERROR_NE;
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  /* UART Over-Run interrupt occurred ----------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  { 
    __HAL_UART_CLEAR_OREFLAG(huart);

    huart->ErrorCode |= HAL_UART_ERROR_ORE;
  }

  tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
  tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
  if(tmp2 == 0x32)
    tmp2=0x32;
  /* UART in mode Receiver ---------------------------------------------------*/
  if((tmp1 != RESET) && (tmp2 != RESET))
  {         
     HAL_UART_Receive(huart, buff, 8, 0xFF); // FOR receive data on interrupt base :chandan
  }
相关问题