硬汉嵌入式论坛

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

[技术讨论] F4 使用多个Uart fifo 进入中断函数 但未查询到中断标志的问题

[复制链接]

7

主题

10

回帖

31

积分

新手上路

积分
31
发表于 2024-9-19 11:00:25 | 显示全部楼层 |阅读模式
stm32f407 使用5个串口进行通讯,还有2个外部中断触发和ADC DMA中断。问题现象是,运行1-2个小时后程序卡死,仿真发现是串口2中断函数无法退出, 进入串口2中断后,未进入接收中断,发送缓冲区空中断,发送完毕中断,无法清除中断标志。

查看寄存器状态USART2-CR1:0x202C    TXEIE为0 被禁止     TCIE为0 被禁止   RXNEIE为1 被使能     但 USART2-SR:0x00C0    TXE为1 被触发   TC为1 被触发  RXNE为0 未被触发
请问是什么原因导致的这个问题   程序中 其他中断太多吗   还是中断优先级的问题?
程序卡死后  在串口中断中打断点   逐步运行后  将断点去掉  程序恢复运行
bsp_uart_fifo.c 是V1.1版本  不知和当前版本有无关系


*        模块名称 : 串口中断+FIFO驱动模块
*        文件名称 : bsp_uart_fifo.c
*        版    本 : V1.0
*        说    明 : 采用串口中断+FIFO模式实现多个串口的同时访问
*        修改记录 :
*                版本号  日期       作者    说明
*                V1.0    2013-02-01 armfly  正式发布
*                V1.1    2013-06-09 armfly  FiFo结构增加TxCount成员变量,方便判断缓冲区满; 增加 清FiFo的函数





/*
*********************************************************************************************************
*        函 数 名: UartIRQ
*        功能说明: 供中断服务程序调用,通用串口中断处理函数
*        形    参: _pUart : 串口设备
*        返 回 值: 无
*********************************************************************************************************
*/
static void UartIRQ(UART_T *_pUart)
{
        /* 处理接收中断  */
        if (USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET)
        {
        
                /* 从串口接收数据寄存器读取数据存放到接收FIFO */
                _pUart->pRxBuf[_pUart->usRxWrite] = USART_ReceiveData(_pUart->uart);
                if (++_pUart->usRxWrite >= _pUart->usRxBufSize)
                {
                        _pUart->usRxWrite = 0;
                }
                if (_pUart->usRxCount < _pUart->usRxBufSize)
                {
                        _pUart->usRxCount++;
                }

                /* 回调函数,通知应用程序收到新数据,一般是发送1个消息或者设置一个标记 */
                //if (_pUart->usRxWrite == _pUart->usRxRead)
                if (_pUart->usRxCount == 1)
                {
                        if (_pUart->ReciveNew)
                        {
                                _pUart->ReciveNew();
                        }
                }               
        }

        /* 处理发送缓冲区空中断 */
        if (USART_GetITStatus(_pUart->uart, USART_IT_TXE) != RESET)
        {
                //if (_pUart->usTxRead == _pUart->usTxWrite)
                if (_pUart->usTxCount == 0)
                {
                        /* 发送缓冲区的数据已取完时, 禁止发送缓冲区空中断 (注意:此时最后1个数据还未真正发送完毕)*/
                        USART_ITConfig(_pUart->uart, USART_IT_TXE, DISABLE);

                        /* 使能数据发送完毕中断 */
                        USART_ITConfig(_pUart->uart, USART_IT_TC, ENABLE);
                }
                else
                {
                        /* 从发送FIFO取1个字节写入串口发送数据寄存器 */
                        USART_SendData(_pUart->uart, _pUart->pTxBuf[_pUart->usTxRead]);
                        if (++_pUart->usTxRead >= _pUart->usTxBufSize)
                        {
                                _pUart->usTxRead = 0;
                        }
                        _pUart->usTxCount--;
                }

        }
        /* 数据bit位全部发送完毕的中断 */
        else if (USART_GetITStatus(_pUart->uart, USART_IT_TC) != RESET)
        {
                //if (_pUart->usTxRead == _pUart->usTxWrite)
                if (_pUart->usTxCount == 0)
                {
                        /* 如果发送FIFO的数据全部发送完毕,禁止数据发送完毕中断 */
                        USART_ITConfig(_pUart->uart, USART_IT_TC, DISABLE);

                        /* 回调函数, 一般用来处理RS485通信,将RS485芯片设置为接收模式,避免抢占总线 */
                        if (_pUart->SendOver)
                        {
                                _pUart->SendOver();
                        }
                }
                else
                {
                        /* 正常情况下,不会进入此分支 */
                       
                        /* 如果发送FIFO的数据还未完毕,则从发送FIFO取1个数据写入发送数据寄存器 */
                        USART_SendData(_pUart->uart, _pUart->pTxBuf[_pUart->usTxRead]);
                        if (++_pUart->usTxRead >= _pUart->usTxBufSize)
                        {
                                _pUart->usTxRead = 0;
                        }
                        _pUart->usTxCount--;
                }
        }
}



   

进入中断函数 但未查询到中断标志位

进入中断函数  但未查询到中断标志位
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-9-19 15:02:10 | 显示全部楼层
注意这个问题没

V5,V6,V7板子串口FIFO驱动中的串口2未开启发送,因为这个接口用于GPS,仅需接收,移植要注意
https://www.armbbs.cn/forum.php? ... 7592&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

7

主题

10

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2024-9-19 15:58:56 | 显示全部楼层
eric2013 发表于 2024-9-19 15:02
注意这个问题没

V5,V6,V7板子串口FIFO驱动中的串口2未开启发送,因为这个接口用于GPS,仅需接收,移植 ...


        /* 第2步: 配置串口硬件参数 */
        USART_InitStructure.USART_BaudRate = UART2_BAUD;        /* 波特率 */
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No ;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx| USART_Mode_Tx;                /* 仅选择接收模式 */
        USART_Init(USART2, &USART_InitStructure);

串口2开启了发送和接收  只是未对接收的数据做处理,程序运行1个小时后 才出现的问题
当前串口的使用情况是

/* 定义串口波特率和FIFO缓冲区大小,分为发送缓冲区和接收缓冲区, 支持全双工 */
#if UART1_FIFO_EN == 1
        #define UART1_BAUD                        9600
        #define UART1_TX_BUF_SIZE        1*1024
        #define UART1_RX_BUF_SIZE        1*1024
#endif

#if UART2_FIFO_EN == 1
        #define UART2_BAUD                        115200
        #define UART2_TX_BUF_SIZE        4*1024
        #define UART2_RX_BUF_SIZE        4*1024
#endif

#if UART3_FIFO_EN == 1
        #define UART3_BAUD                        9600
        #define UART3_TX_BUF_SIZE        1*1024
        #define UART3_RX_BUF_SIZE        1*1024
#endif

#if UART4_FIFO_EN == 1
        #define UART4_BAUD                        9600
        #define UART4_TX_BUF_SIZE        4*1024
        #define UART4_RX_BUF_SIZE        4*1024
#endif

#if UART5_FIFO_EN == 1
        #define UART5_BAUD                        9600
        #define UART5_TX_BUF_SIZE        4*1024
        #define UART5_RX_BUF_SIZE        4*1024
#endif


根据寄存器状态   进入中断  中断标志位的TXE为1   TC为1   这两个中断标志位被置位  明明关闭了这两个中断  不知为什么会被再次置位
论坛中 有人遇到的问题是 触发了ORE中断 但是无法清除中断标志位     但是  我查看ORE中断标志位  未被置1   
https://www.armbbs.cn/forum.php? ... E%BF%DA%D6%D0%B6%CF
当前遇到的问题是 进入到了串口中断 但是没有对应的中断标志位  被置位

回复

使用道具 举报

95

主题

529

回帖

829

积分

金牌会员

积分
829
发表于 2024-9-19 16:29:42 | 显示全部楼层
你在中断里把没有用到的其他中断都清除一下。
共产主义一定胜利!
回复

使用道具 举报

0

主题

33

回帖

33

积分

新手上路

积分
33
发表于 2024-9-19 22:58:46 | 显示全部楼层
不停的收发短小数据,比如MODBUS_RTU,这FIFO好像没用
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-9-20 09:23:37 | 显示全部楼层
打翻的酱油瓶 发表于 2024-9-19 15:58
/* 第2步: 配置串口硬件参数 */
        USART_InitStructure.USART_BaudRate = UART2_BAUD;        /* 波特率 */
...

这个可以排查下,UartIRQ(UART_T *_pUart)在各个中断里面都有调用。

你把这个函数在你的串口2中断里面展开,函数里面的除了标志位判断和清除操作,其他所有操作都注释掉。

这样就就跟串口中断没关系了,你排查下是否还有问题。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-29 06:27 , Processed in 0.332237 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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