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

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

byronsong 回答时间: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,真是无语了
xiaoxiao0932 回答时间:2019-8-9 10:26:50
电子星辰 发表于 2019-8-9 09:53
有可能是与串口发数据冲突了。
仔细看了你的代码,好像不会冲突占用。不过你可以试着先把发送代码注释,测 ...

我是要用接收中断来接数据,在主循环中累计到一定数据再发出去,现在收不到数,不会触发发送数据,仅仅是想不接收发送跑通
byronsong 回答时间:2019-8-9 11:36:54
xiaoxiao0932 发表于 2019-8-9 09:56
非常感谢提供思路,我尝试了一下,上电后程序会进入错误中断的回调函数,我加入了重新使能中断接收一字节 ...

降低波特率试试。
xiaoxiao0932 回答时间:2019-8-9 13:49:57

降低波特率还是不行,我找块开发板试试吧,好无奈了
skyi 回答时间:2019-8-9 16:10:11
HAL_UART_Receive_IT是阻塞等待的吧,应该是不能放到中断里去的

评分

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

查看全部评分

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版