xiaoxiao0932 发表于 2019-8-8 17:56:41

STM32F746使用HAL库串口无法中断收数据

使用串口1中断收发数据,可以发送,单独测试过了,串口中断接收数据出现问题,现象是在板子上电后,在外界没有给串口发数据的时候会进入HAL_UART_RxCpltCallback回调函数1次,然后就再也进不去了,上位机通过USB转422/485的转接线,给板子发数据,串口无法进入接收中断,在进入while循环前,我开启了一次接收中断,在回调函数中如果收到数据,我再次开启接收中断,这个逻辑上有什么问题啊?怎么就是进不了串口接收中断呢?同样的操作串口2,也是无法进入串口中断。
感觉是HAL库处理有问题,但是找不到根本所在啊,还请使用HAL库操作过串口中断的大神们,指点迷津啊{:3_59:}
代码很简单,大体如下:

int main(void)
{
    HAL_Init();
    /* Configure the system clock */
    SystemClock_Config();
    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_GFXSIMULATOR_Init();
    MX_USART1_UART_Init();
               
    /* USER CODE BEGIN 2 */
    HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
    /* USER CODE END 2 */

    /* Infinite loop */
    while (1)
    {
         if(Uart1_Rx_Cnt>=7)
            {
                if(HAL_UART_Transmit_IT(&UartHandle1, (uint8_t*)&Usart_RxBuffer1, 7)!= HAL_OK)
                {
                  /* Transfer error in transmission process */
                  Error_Handler();
                }
                Uart1_Rx_Cnt = 0;
            }

    }
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
      if(UartHandle->Instance == USART1)
      {
            Usart_RxBuffer1 = aRxBuffer;   //接收数据转存

            HAL_UART_Receive_IT(&UartHandle1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
      }
}
static void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 921600;
    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();
    }
}

static void MX_GPIO_Init(void)
{
    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOA_CLK_ENABLE();
}

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if(huart->Instance==USART1)
    {
      /* Peripheral 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);

    }

}

wenyangzeng 发表于 2019-8-8 20:11:36

中断接收完成后,HAL自动禁止UART中断,需要在主循环函数中执行:

HAL_UART_Receive_IT(&huart1,(uint8_t *)&aRxBuffer,1);

xiaoxiao0932 发表于 2019-8-9 08:57:19

wenyangzeng 发表于 2019-8-8 20:11
中断接收完成后,HAL自动禁止UART中断,需要在主循环函数中执行:

HAL_UART_Receive_IT(&huart1,(uint8_t...

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
      if(UartHandle->Instance == USART1)
      {
            Usart_RxBuffer1 = aRxBuffer;   //接收数据转存

            HAL_UART_Receive_IT(&UartHandle1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
      }
}

我放到接收中断的回调函数里了,这个跟放到主循环中有什么区别吗?

xiaoxiao0932 发表于 2019-8-9 09:10:51

HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
{
uint32_t temp1= 0x00U, temp2 = 0x00U;
temp1 = huart->gState;
temp2 = huart->RxState;

return (HAL_UART_StateTypeDef)(temp1 | temp2);
}
跟踪发现接收状态
huart->RxState=0x22 HAL_UART_STATE_BUSY_RX

songshiqun2010 发表于 2019-8-9 09:25:33

有可能触发了错误中断
//void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
//{
//if(huart->Instance == USART1){
//    HAL_UART_Receive_IT(&huart1,usart1_rx_buf,1);
//}
//}
检查下SR寄存器,根据状态做相应的回调处理。
上述代码,只要出错,就重新使能中断接收一字节。

wenyangzeng 发表于 2019-8-9 09:39:58

xiaoxiao0932 发表于 2019-8-9 08:57
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
      if(UartHandle->Instance ==...

不该放在中断函数里的。

电子星辰 发表于 2019-8-9 09:53:21

有可能是与串口发数据冲突了。
仔细看了你的代码,好像不会冲突占用。不过你可以试着先把发送代码注释,测试一下。

xiaoxiao0932 发表于 2019-8-9 09:56:55

songshiqun2010 发表于 2019-8-9 09:25
有可能触发了错误中断

检查下SR寄存器,根据状态做相应的回调处理。


非常感谢提供思路,我尝试了一下,上电后程序会进入错误中断的回调函数,我加入了重新使能中断接收一字节
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1){
    HAL_UART_Receive_IT(&huart1,usart1_rx_buf,1);
}
}
但是还是无法接收到数据啊,状态还是一直huart->RxState=0x22 HAL_UART_STATE_BUSY_RX
就没响应了,不进接收中断

xiaoxiao0932 发表于 2019-8-9 09:59:06

wenyangzeng 发表于 2019-8-9 09:39
不该放在中断函数里的。

我试试放到主循环中

xiaoxiao0932 发表于 2019-8-9 10:23:35

wenyangzeng 发表于 2019-8-9 09:39
不该放在中断函数里的。

我测试了把 HAL_UART_Receive_IT(&UartHandle1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
放到主循环中,还是进步了中断,状态一直是huart->RxState=0x22 HAL_UART_STATE_BUSY_RX,我强制修改状态为HAL_UART_STATE_READY,下次开启接收中断,状态又变成了HAL_UART_STATE_BUSY_RX,真是无语了
页: [1] 2
查看完整版本: STM32F746使用HAL库串口无法中断收数据