你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

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

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[Uart1_Rx_Cnt++] = 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);

    }

}

收藏 评论13 发布时间:2019-8-8 17:56

举报

13个回答
wenyangzeng 回答时间:2019-8-8 20:11:36
中断接收完成后,HAL自动禁止UART中断,需要在主循环函数中执行:

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

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

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[Uart1_Rx_Cnt++] = 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
有可能触发了错误中断
  1. //void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
  2. //{
  3. //  if(huart->Instance == USART1){
  4. //    HAL_UART_Receive_IT(&huart1,usart1_rx_buf,1);
  5. //  }
  6. //}
复制代码

检查下SR寄存器,根据状态做相应的回调处理。
上述代码,只要出错,就重新使能中断接收一字节。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

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

评分

参与人数 1蝴蝶豆 +1 收起 理由
STMCU + 1

查看全部评分

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,真是无语了
12下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版