uart_rxfifo_tout中断问题

AI_stark
Posts: 1
Joined: Thu Jan 13, 2022 3:05 am

uart_rxfifo_tout中断问题

Postby AI_stark » Sun Jan 23, 2022 4:34 pm

开启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 <stdio.h>
#include <string.h>
#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 1024
uart_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);
	}
}

fatcatLA
Posts: 2
Joined: Sat Mar 12, 2022 3:17 am

Re: uart_rxfifo_tout中断问题

Postby fatcatLA » Sat Mar 12, 2022 3:20 am

老哥试试把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);
}

}

Who is online

Users browsing this forum: No registered users and 42 guests