硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5158|回复: 7
收起左侧

[STM32F7] STM32的串口接收中断接收一个字节后,接收中断使能就被清除,无法进入中断

[复制链接]

5

主题

95

回帖

110

积分

初级会员

积分
110
发表于 2019-12-2 18:46:14 | 显示全部楼层 |阅读模式
本帖最后由 xiaomeng 于 2019-12-2 19:28 编辑

采用HAL库,调试串口中断接收数据时发现,STM32的串口接收中断在接收一个字节后,接收中断使能位就会被自动清除,再有新的数据就无法进入中断,无法正常接收数据,想请教各位是什么情况导致的?

初始化代码如下:
/* 配置Tx引脚为复用功能  */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
               
/* 配置Rx引脚为复用功能 */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/*串口1中断初始化 */
HAL_NVIC_SetPriority(USART1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);

__HAL_UART_ENABLE_IT(&UartCtrlHandle,UART_IT_RXNE);


中断处理如下:
if (__HAL_UART_GET_IT( &UartCtrlHandle, UART_IT_RXNE ) != RESET)
{
        HAL_UART_Receive(&UartCtrlHandle, &rx_dat, 1, 1000);

        HAL_UART_IRQHandler(&UartCtrlHandle);
}
回复

使用道具 举报

0

主题

105

回帖

105

积分

初级会员

积分
105
发表于 2019-12-2 23:40:52 | 显示全部楼层
HAL_UART_IRQHandler(&UartCtrlHandle); 服务函数里设置的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2019-12-3 09:03:51 | 显示全部楼层
【STM32H743实验例程】实验13:STM32H743串口中断方式收发
http://www.armbbs.cn/forum.php?m ... 6245&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

5

主题

95

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2019-12-3 09:52:48 | 显示全部楼层
本帖最后由 xiaomeng 于 2019-12-4 17:51 编辑
barryxiao 发表于 2019-12-2 23:40
HAL_UART_IRQHandler(&UartCtrlHandle); 服务函数里设置的

是因为这个函数造成的,因为检测到OVERRUN,所以调用该函数后清除了接收中断的使能位;
回复

使用道具 举报

5

主题

95

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2019-12-4 11:47:49 | 显示全部楼层
xiaomeng 发表于 2019-12-3 09:52
是因为这个函数造成的,但是不清楚接收出了什么问题;配置的另一个串口可以正常中断接收数据,没出现这个 ...

感觉还是没有根本解决问题。
void DEBUG_UARTx_IRQHandler(void)
{
        static uint8_t State=0;                /* 状态机 */
        static uint8_t i=0;                        /* 某一个状态接收到的字节数 */
        uint8_t rx_dat=0;
        /* 不采用HAL库,直接寄存器判断,读取数据进行处理 */
        if (__HAL_UART_GET_IT( &DebugUartHandle, UART_IT_RXNE ) != RESET)
        {
                HAL_UART_Receive(&DebugUartHandle, &rx_dat, 1, 1000);
        }
        switch(State)
        {
                /* 帧头的第一个字节0x55检测 */
                case 0:       
                        if(rx_dat==0x55)          State = 1;
                        else                                State = 0;
                        break;
                       
                /* 帧头的第2个字节0xAA检测 */
                case 1:
                        if(rx_dat==0xAA)   
                        {
                                i=0;
                                State=2;
                        }
                        else
                                State=0;
                        break;
               
                /* 数据接收缓冲区 */
                case 2:                  
                                bsp_DebugUart.rx_buffer[2+i++] = rx_dat;
                                if(i==8)
                                {   /* 一帧接收完成后,使能DMA接收,数据以帧头对其 */
                                        i = 0;
                                        State = 0;
                                        bsp_DebugUart.rx_ok_flag = 1; /* 帧接收完成标志位 */
                                        /*
                                                关闭接收中断,
                                                使能串口DMA接收模式
                                        */
                                        __HAL_UART_DISABLE_IT(&DebugUartHandle,UART_IT_RXNE);
                                        /* 使能DMA传输完成中断 */
                                        __HAL_DMA_ENABLE_IT(&DMAUartRxDebugHandle,DMA_IT_TC);       
                                        /* 开始使用DMA进行数据的接收 */
                                        HAL_UART_Receive_DMA(&DebugUartHandle,(uint8_t *)bsp_DebugUart.rx_buffer,10);
                                }
                        break;

                default:
                                i = 0;
                                State = 0;
                        break;
        }  
        /* 调用 HAL 库中断处理公用函数,清除中断标志位 */
        HAL_UART_IRQHandler(&DebugUartHandle);
}
上面这个可以使用,接收一帧数据后,能够成功开启DMA接收。
回复

使用道具 举报

5

主题

95

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2019-12-4 14:04:14 | 显示全部楼层
本帖最后由 xiaomeng 于 2019-12-4 17:52 编辑

使用另一个串口的话,一工作就会导致Overrun,调用HAL_UART_IRQHandler(&UartCtrlHandle);就会清除接收中断使能位。
导致出现overrun是因为使用rtos的原因。
回复

使用道具 举报

5

主题

95

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2019-12-4 16:41:28 | 显示全部楼层
在裸机上没有问题 。上RTOS就会出现这种情况。配置应该没有问题。
继续查找
回复

使用道具 举报

5

主题

95

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2019-12-9 18:47:40 | 显示全部楼层
xiaomeng 发表于 2019-12-4 16:41
在裸机上没有问题 。上RTOS就会出现这种情况。配置应该没有问题。
继续查找

在rtos的另一个任务里关闭中断引起的
http://www.armbbs.cn/forum.php?m ... &extra=page%3D1
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-2 10:42 , Processed in 0.186871 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表