串口中断相关
Posted: Wed Jul 20, 2022 11:14 am
-问题由来:在examples中,有uart_event的具体使用方法,但我想用串口中断读取GPS数据,我用uart_event模式在解析GPS数据时,会出现FIFO Overflow的问题,虽然examples中有nmea0183_parser案例来解析GPS数据,但是这个example对我来说太复杂了,于是我想用最原始的串口中断方法来解析GPS数据,但是我在做串口中断测试时,发现一旦我用uart_isr_register注册中断函数uart1_irq_handler后,就会报错Guru Meditation Error: Core 0 panic'ed (Interrupt wdt timeout on CPU0),我不明白为什么我的中断函数这么简单,看门狗还能跑飞,以下是我的代码。
代码解释:UART1与GPS模块相连,UART0与USB相连,UART1触发中断后,标志位rx_flag置1,在main中从UART1 FIFO中读取数据,用UART0向电脑的串口调试助手打印数据。
[Codebox]
#include <stdio.h>
#include <string.h>
#include "driver/uart.h"
#include "soc/uart_struct.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#define EX_UART_NUM UART_NUM_1
#define BUF_SIZE (1024)
#define RD_BUF_SIZE (BUF_SIZE)
int rx_flag;
static void IRAM_ATTR uart1_irq_handler(void *arg)
{
rx_flag = 1;
}
void uart2_init(void)
{
//串口一些基本参数的配置
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
uart_param_config(EX_UART_NUM, &uart_config);
uart_param_config(UART_NUM_0, &uart_config);
//设置串口使用的引脚
uart_set_pin(EX_UART_NUM, GPIO_NUM_17, GPIO_NUM_18, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
//先uart_driver_install安装驱动,再把中断服务给释放掉
uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0);
uart_driver_install(UART_NUM_0, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0);
uart_isr_free(EX_UART_NUM);
//重新注册中断服务函数
uart_isr_handle_t handle;
uart_isr_register(EX_UART_NUM, uart1_irq_handler, NULL, 0, &handle);
//使能串口接收中断
uart_enable_rx_intr(EX_UART_NUM);
}
void app_main(void)
{
uart2_init();
uint8_t *dtmp = (uint8_t *)malloc(RD_BUF_SIZE);
while (1)
{
if (rx_flag == 1)
{
rx_flag = 0;
bzero(dtmp, RD_BUF_SIZE);
int len = uart_read_bytes(EX_UART_NUM, dtmp, RD_BUF_SIZE, portMAX_DELAY);
uart_write_bytes(UART_NUM_0, (const char *)dtmp, len);
}
}
}
[/Codebox]
图片为报错信息
代码解释:UART1与GPS模块相连,UART0与USB相连,UART1触发中断后,标志位rx_flag置1,在main中从UART1 FIFO中读取数据,用UART0向电脑的串口调试助手打印数据。
[Codebox]
#include <stdio.h>
#include <string.h>
#include "driver/uart.h"
#include "soc/uart_struct.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#define EX_UART_NUM UART_NUM_1
#define BUF_SIZE (1024)
#define RD_BUF_SIZE (BUF_SIZE)
int rx_flag;
static void IRAM_ATTR uart1_irq_handler(void *arg)
{
rx_flag = 1;
}
void uart2_init(void)
{
//串口一些基本参数的配置
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
uart_param_config(EX_UART_NUM, &uart_config);
uart_param_config(UART_NUM_0, &uart_config);
//设置串口使用的引脚
uart_set_pin(EX_UART_NUM, GPIO_NUM_17, GPIO_NUM_18, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
//先uart_driver_install安装驱动,再把中断服务给释放掉
uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0);
uart_driver_install(UART_NUM_0, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0);
uart_isr_free(EX_UART_NUM);
//重新注册中断服务函数
uart_isr_handle_t handle;
uart_isr_register(EX_UART_NUM, uart1_irq_handler, NULL, 0, &handle);
//使能串口接收中断
uart_enable_rx_intr(EX_UART_NUM);
}
void app_main(void)
{
uart2_init();
uint8_t *dtmp = (uint8_t *)malloc(RD_BUF_SIZE);
while (1)
{
if (rx_flag == 1)
{
rx_flag = 0;
bzero(dtmp, RD_BUF_SIZE);
int len = uart_read_bytes(EX_UART_NUM, dtmp, RD_BUF_SIZE, portMAX_DELAY);
uart_write_bytes(UART_NUM_0, (const char *)dtmp, len);
}
}
}
[/Codebox]
图片为报错信息