打印
[应用相关]

AT32F403A串口空闲中断多次触发

[复制链接]
98|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 哪里需要我了 于 2025-1-14 16:50 编辑

现在已经实现了带缓冲区的中断收发,这两个中断没啥问题。想空闲中断处理下不定长数据,发现有点不对劲,好像是反复进入中断,改成打印以后确实是这样,明明我测试的数据一秒发送一次,按道理空闲中断不应该一秒触发一次吗?实际打印出来一秒就上千次。
我用的work bench版本是1.1.04,是否要用最新版?
int cnt = 0;
void USART1_IRQHandler(void)
{
        extern QueueHandle_t xQueue_Usart1;
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // 声明并初始化xHigherPriorityTaskWoken
        static uint16_t data_len = 0;
        
    uint8_t data;
    uint16_t usedCapacityOfBuffer = 0;
    uint16_t realCountPutBuffer = 0;
        
        if(usart_interrupt_flag_get(USART1, USART_RDBF_FLAG) != RESET) {
        // 获取串口寄存器内数据寄存器的有效数据
                data = usart_data_receive(USART1);
        // 向RX环形缓冲区写入一个字节
                realCountPutBuffer = RingBuf_Put(&s_uart1ReadRingBuffer, &data, 1);
        // 当前环形缓冲区已使用的容量 = 最大值 - 环形缓冲区未使用的大小
        usedCapacityOfBuffer = UART1_READ_BUF_SIZE - RingBuf_GetUnusedSize(&s_uart1ReadRingBuffer);
        // 若 当前环形缓冲区已使用的容量 大于 缓冲区曾经使用过的最大容量,则更新缓冲区曾经使用过的最大容量状态,否则保持原有值
        s_uart1ReadBufferState.maxUsedCapacityOfBuffer =
            usedCapacityOfBuffer > s_uart1ReadBufferState.maxUsedCapacityOfBuffer ? usedCapacityOfBuffer
                                                                                  : s_uart1ReadBufferState.maxUsedCapacityOfBuffer;
        // 向RX环形缓冲区写入一个字节失败,则记录一次失败状态
        s_uart1ReadBufferState.countOfLostData += 1 - realCountPutBuffer;

        // 记录写入RC环形缓冲区内长度累加
        data_len = data_len + realCountPutBuffer;
        }

    if (usart_interrupt_flag_get(USART1, USART_IDLEF_FLAG) != RESET) {
                cnt++;
                printf("cnt = %d\n", cnt);
//                if (xQueueSendFromISR(xQueue_Usart1, &data_len, &xHigherPriorityTaskWoken) == pdPASS) {
//                        // 数据发送成功
//                        data_len = 0;
//                        printf("Data len sent to queue: %d\n", data_len);
//                } else {
//                        // 队列已满,发送失败
//                        printf("Failed to send data to queue.\n");
//                }
                // 如果有更高优先级的任务就绪,请求上下文切换
//                portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        }

        
        if(usart_interrupt_flag_get(USART1, USART_TDBE_FLAG) != RESET) {
                if (RingBuf_Get(&s_uart1WriteRingBuffer, &data, 1)) {
            // 将一个字节数据写入UART数据寄存器
            usart_data_transmit(USART1, (uint16_t)data);
        } else {
            // 否则关闭串口中断发送
            usart_interrupt_enable(USART1, USART_TDBE_INT, FALSE);
        }
    }
}




Z`R_4Y_J%QWQ04_G6R_$WDB.png (167.19 KB )

Z`R_4Y_J%QWQ04_G6R_$WDB.png

1.png (62.92 KB )

1.png

2.png (24.49 KB )

2.png

使用特权

评论回复
沙发
哪里需要我了|  楼主 | 2025-1-14 15:30 | 只看该作者
请问各位,work bench是如何更新的?这work bench点更新为啥是下载一个zip,是手动解压覆盖吗?旧work bench版本是1.1.04,旧版本的工程迁移到新的work bench上以后有什么注意事项吗?

使用特权

评论回复
板凳
哪里需要我了|  楼主 | 2025-1-14 15:35 | 只看该作者
我看到论坛有个类似帖子,不过是去年九月份的事了

使用特权

评论回复
地板
哪里需要我了|  楼主 | 2025-1-14 16:49 | 只看该作者
问题已解决,空闲中断需要软件复位,把下面这段加进中断回调函数里面即可
volatile uint32_t temp;
temp = USARTx->STS; // 先读USART状态寄存器
temp = USARTx->DT;  // 再读USART数据寄存器


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

13

帖子

0

粉丝