乐鑫技术交流
直播中

李斌

7年用户 1404经验值
私信 关注
[问答]

开启uart_rxfifo_tout中断一次性发送数据给单片机,为什么会触发两次rxfifo_tout中断?

开启uart_rxfifo_tout中断,一次性发送数据给单片机,理论上串口接收超时中断只能触发一次中断,但却触发了两次rxfifo_tout中断。求解答。
发送数据Code: Select all
0x61 0x61 0x61
总返回数据Code: Select all
0x61 0x61 0x61 0x4F 0x4B 0x01 0x4F 0x4B 0x02
(0x4F 0x4B为OK)Code: Select all
#include #include #include "soc/uart_periph.h"#include "driver/uart.h"#include "soc/uhci_reg.h"#include "driver/gpio.h"#include "esp_event.h"#include "esp_log.h"TaskHandle_t rx_task_handle;#define UART_LOG "uart_log"                        //串口TAG#define UART1_RX_IO GPIO_NUM_9                //UART1_RX引脚 -> GPIO9#define UART1_TX_IO GPIO_NUM_10                //UART1_TX引脚 -> GPIO10#define BUFF_SIZE 1024uart_isr_handle_t uart1_handle;uint8_t rxbuf[128];uint16_t urxlen;static void IRAM_ATTR uart_intr_handle(void *arg){        volatile uart_dev_t *uart = &UART1;        static uint8_t count = 0;        count++;        volatile uint8_t flag = 0;                                                //标志位判断是否触发rxfifo_tout中断        if(uart->int_st.rxfifo_tout == 1)        {                uart_clear_intr_status(UART_NUM_1, UART_RXFIFO_TOUT_INT_CLR);                flag = 1;                                                                //触发rxfifo_tout中断,标志位置1        }    while (uart->status.rxfifo_cnt) {                uint8_t c = uart->ahb_fifo.rw_byte;                uart_tx_chars(UART_NUM_1, (char *)&c, 1);        //返回数据    }        if(flag)                uart_tx_chars(UART_NUM_1, "OK", 2);                //进入rxfifo_tout中断返回OK        uart_tx_chars(UART_NUM_1,(char *)&count,1);                //返回当前进入中断次数}void app_main(void){        uart_config_t uart_conf = {                        .baud_rate         = 115200,                                                //波特率:115200                        .data_bits         = UART_DATA_8_BITS,                                //数据位:八位                        .parity                = UART_PARITY_DISABLE,                        //校验位:不校验                        .stop_bits        = UART_STOP_BITS_1,                                //停止位:1                        .flow_ctrl        = UART_HW_FLOWCTRL_DISABLE,                //硬件控制流:不启用                        .source_clk = UART_SCLK_APB,                                //时钟总线:APB总线        };        uart_port_t uart_port = UART_NUM_1;                                        //UART1        uart_param_config(uart_port, &uart_conf);        uart_set_pin(uart_port, UART1_TX_IO, UART1_RX_IO, GPIO_NUM_NC, GPIO_NUM_NC);        uart_driver_install(uart_port, BUFF_SIZE*2, 0, 0, NULL, 0);        //关闭预先创建的uart中断        uart_isr_free(uart_port);        uart_isr_register(uart_port, uart_intr_handle,NULL, ESP_INTR_FLAG_IRAM, &uart1_handle);        uart_disable_intr_mask(uart_port, 0x001FFFFF);                                        //关闭预先的串口中断        uart_enable_intr_mask(uart_port, UART_RXFIFO_TOUT_INT_ENA);                //开启RXFIFO_TOUT中断        while(1)        {                vTaskDelay(1);        }}

                                      

回帖(2)

陈秀英

2024-6-18 09:36:06
试试把uart_clear_intr_status(UART_NUM_1, UART_RXFIFO_TOUT_INT_CLR); 放到中断函数完成所有操作的最后面
我用你的代码试了,放在最后面的时候不会触发两次
//中断服务函数放在IRAM中执行,所以在这里定义的时候要添加IRAM_ATTR
static void IRAM_ATTR uart2_irq_handler(void *arg)
{
        //uart结构体指针指向串口中断寄存器
        volatile uart_dev_t *uart = &UART2;

        //判断是什么中断触发了
        if(uart->int_st.rxfifo_tout == 1)
        {
                //判断数据寄存器里是否有数据
                while (uart->status.rxfifo_cnt)
                {
                        //此处改为装入自己的buf缓冲区
                        uint8_t c = uart->fifo.rw_byte;
                        //打印,中断内不可使用log打印
                        uart_write_bytes(UART_NUM_2, (char *)&c, 1);  //把接收的数据重新打印出来
                }
                //清除中断标志位
                //uart_write_bytes(UART_NUM_2, "uart2_irq_handler", 15);        //把接收的数据重新打印出来
                uart_clear_intr_status(UART_NUM_2, UART_RXFIFO_TOUT_INT_CLR);
        }

}
                                                                                                                                                                                                                       
举报

京五环以外

2024-6-18 15:35:56
根据您的描述,您在使用单片机时遇到了一个问题:在开启uart_rxfifo_tout中断后,一次性发送数据给单片机,但触发了两次rxfifo_tout中断。为了解决这个问题,我们可以从以下几个方面进行分析:

1. 检查中断配置:首先,请确保您正确配置了中断。检查您的中断设置,确保uart_rxfifo_tout中断已经正确启用。

2. 检查数据发送和接收逻辑:请检查您的发送和接收数据的逻辑,确保发送的数据与接收的数据一致。如果发送的数据与接收的数据不一致,可能会导致中断触发多次。

3. 检查硬件连接:请检查您的硬件连接,确保UART通信线路没有故障,如接触不良或线路干扰等。

4. 检查中断服务程序:请检查您的中断服务程序,确保在中断触发时,正确处理了接收到的数据,并在处理完成后清除了中断标志。如果中断标志没有被正确清除,可能会导致中断再次触发。

5. 检查中断优先级:请检查您的中断优先级设置,确保uart_rxfifo_tout中断的优先级正确。如果中断优先级设置不正确,可能会导致中断服务程序执行不完全,从而触发多次中断。

6. 检查软件版本和硬件兼容性:请确保您使用的软件版本与您的硬件兼容。如果软件版本与硬件不兼容,可能会导致一些意外的行为,如中断触发多次。

综上所述,要解决这个问题,您需要从多个方面进行排查。希望这些建议能帮助您找到问题的原因并解决它。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分