【ESP32学习笔记】#外设篇#(3)串口通信(UART)

一、简介

  • 官方文档:UART
  • ESP32 有 3 个 UART 控制器(UART0UART1UART2),它们具有一组相同的寄存器。
  • 每个 UART 控制器均可独立配置参数,如波特率、数据位长度、位排序、停止位数量、奇偶校验位等。
  • 支持异步通信(RS232 和 RS485)和 IrDA。
  • 通信速率可达到 5 Mbps。
  • 支持 CTS 和 RTS 信号的硬件管理以及软件流控(XON 和 XOFF)。
  • 3 个接口均可被 DMA 访问或者 CPU 直接访问。
  • 全双工异步通信
  • 支持 UART 唤醒模式
  • 支持波特率自检测功能
  • UART 有两个时钟源:80-MHz APB_CLK 以及参考时钟 REF_TICK
  • 3 个 UART 的发送 FIFO 以及接收 FIFO 共享 1024 × 8-bit RAM。
    UART 共享 RAM 图:
    在这里插入图片描述

二、配置和使用

1、初始化示例:

const int uart_num = UART_NUM_0;
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_CTS_RTS,	// 硬件流控模式(cts/rts)
    // .rx_flow_ctrl_thresh = 122,	// 硬件 RTS 阈值
    // .source_clk = ,	// 源时钟选择
};
/* 设置 UART 通讯参数 */
uart_param_config(uart_num, &uart_config);

/* 设置 UART 引脚 */
uart_set_pin(uart_num , GPIO_NUM_1, GPIO_NUM_3, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

/* 安装驱动程序 */
const int uart_buffer_size = (1024 * 2);
QueueHandle_t uart_queue;
uart_driver_install(uart_num , uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));

// uart_isr_free(uart_num ); //释放中断服务函数

2、发送示例:

char* test_str = "Hello World.\n";

// 发送函数1
uart_write_bytes(uart_num, (const char*)test_str, strlen(test_str));

// 发送函数2 uart_tx_chars 函数不会在 TX FIFO 中等待足够的空间

// 发送函数3 传输结束时增加一个串行中断信号 相当于帧与帧之间增加间隔
uart_write_bytes_with_break(uart_num, "test break\n",strlen("test break\n"), 100);

// 等待发送完成
ESP_ERROR_CHECK(uart_wait_tx_done(uart_num, 100));

3、接收示例:

// Read data from UART.
const int uart_num = UART_NUM_0;
uint8_t data[128];
int length = 0;
ESP_ERROR_CHECK(uart_get_buffered_data_len(uart_num, (size_t*)&length));
length = uart_read_bytes(uart_num, data, length, 100);

4、自定义中断示例:

const int uart_num = UART_NUM_0;
uart_isr_handle_t handle;
// 重新注册自定义中断服务函数,不使用内部中断处理程序
uart_isr_register(uart_num, uart_irq_handler, &uart_num, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM, &handle);
// 使能中断接收 	打开 rxfifo接收满中断,rxfifo超时中断(默认超时时间为10个byte)
uart_enable_rx_intr(uart_num ); 
uart_set_rx_timeout(uart_num, 20); //配置接收超时中断时间,单位为按照当前波特率传输1个bytes的时间

// 中断处理
static void IRAM_ATTR uart_irq_handler(void *arg) {
	volatile uart_dev_t *uart = arg;
	uint8_t recSize=0;
	int uartRxCount = 0;
	uint8_t uartRxBuf[100];

	uart->int_clr.rxfifo_full = 1;
	uart->int_clr.frm_err = 1;
	if(uart->int_st.rxfifo_tout) //检查是否产生超时中断
	{
		uart->int_clr.rxfifo_tout = 1;
		recSize = uart->status.rxfifo_cnt;
		if(recSize!=0){
			while(uart->status.rxfifo_cnt){
				uartRxBuf[uartRxCount++] = uart->fifo.rw_byte; 
			}
		} 
	} 
}

三、官方使用示例

peripherals/uart/

代码示例描述
uart_echo配置 UART 设置、安装 UART 驱动程序以及通过 UART1 接口读取/写入。
uart_events使用模式检测中断报告各种通信事件。
uart_async_rxtxtasks通过同一个 UART 在两个独立的 FreeRTOS 任务中发送和接收数据。
uart_select对 UART 文件描述符使用同步 I/O 多路复用。
uart_echo_rs485设置 UART 驱动程序以在半双工模式下通过 RS485 接口进行通信。此示例类似于外设/uart/uart_echo,但允许通过连接到 ESP32 引脚的 RS485 接口芯片进行通信。
nmea0183_parser通过解析通过 UART 外设从 GPS 接收到的 NMEA0183 数据来获取 GPS 信息。

四、API

driver/uart.h

API描述
uart_driver_install安装 UART 驱动程序并将 UART 设置为默认配置
uart_driver_delete卸载UART驱动
uart_is_driver_installed检查驱动程序是否安装
uart_set_word_length设置 UART 数据位
uart_get_word_length获取 UART 数据位配置
uart_set_stop_bits设置 UART 停止位
uart_get_stop_bits获取 UART 停止位配置
uart_set_parity设置 UART 奇偶校验模式
uart_get_parity获取 UART 奇偶校验模式配置
uart_set_baudrate设置 UART 波特率
uart_get_baudrate获取 UART 波特率配置
uart_set_line_inverse设置 UART 线路反转模式
uart_set_hw_flow_ctrl设置硬件流控制
uart_set_sw_flow_ctrl设置软件流控制
uart_clear_intr_status清除 UART 中断状态
uart_enable_intr_mask设置 UART 中断使能
uart_disable_intr_mask清除 UART 中断使能位
uart_enable_rx_intr启用 UART RX 中断 (RX_FULL & RX_TIMEOUT INTERRUPT)
uart_disable_rx_intr禁用 UART RX 中断 (RX_FULL & RX_TIMEOUT INTERRUPT)
uart_disable_tx_intr禁用 UART TX 中断 (TX_FULL & TX_TIMEOUT INTERRUPT)
uart_enable_tx_intr启用 UART TX 中断 (TX_FULL & TX_TIMEOUT INTERRUPT)
uart_isr_register注册 UART 中断处理程序 (ISR)
uart_isr_free释放由 uart_isr_register 注册的 UART 中断处理程序
uart_set_pin设置 UART 引脚编号
uart_set_rts手动设置 UART RTS 引脚电平
uart_set_dtr手动设置 UART DTR 引脚电平
uart_set_tx_idle_num在 tx FIFO 为空后设置 UART 空闲间隔
uart_param_config设置 UART 配置参数
uart_intr_config配置 UART 中断
uart_wait_tx_done等到 UART TX FIFO 为空
uart_tx_chars从给定的缓冲区和长度将数据发送到 UART 端口
uart_write_bytes从给定的缓冲区和长度向 UART 端口发送数据
uart_write_bytes_with_break从给定的缓冲区和长度向 UART 端口发送数据
uart_read_bytesUART 从 UART 缓冲区读取字节
uart_flushuart_flush_input 的别名。UART 环形缓冲区刷新。会删除 UART RX 缓冲区中的所有数据。
uart_flush_input清除输入缓冲区,删除环形缓冲区中的所有数据。
uart_get_buffered_data_lenUART 获取 RX 环形缓冲区缓存的数据长度
uart_disable_pattern_det_intrUART 禁用模式检测功能。专为“AT 命令”等应用而设计。当硬件检测到一系列相同的字符时,就会触发中断。
uart_enable_pattern_det_intrUART 使能模式检测功能。专为“AT 命令”等应用而设计。当硬件检测到一系列相同的字符时,就会触发中断。
uart_enable_pattern_det_baud_intrUART 使能模式检测功能。专为“AT 命令”等应用而设计。当硬件检测到一系列相同的字符时,就会触发中断。
uart_pattern_pop_pos返回缓冲区中最近检测到的模式位置
uart_pattern_get_pos返回缓冲区中最近检测到的模式位置。
uart_pattern_queue_reset分配一个给定长度的新内存来保存记录在 rx 缓冲区中检测到的模式位置
uart_set_modeUART 设置通信模式
uart_set_rx_full_threshold设置 RX fifo full 的 UART 阈值
uart_set_tx_empty_threshold为 TX fifo 为空设置 UART 阈值
uart_set_rx_timeoutUART 设置 TOUT 功能的阈值超时
uart_get_collision_flag返回 RS485 模式的碰撞检测标志 函数将碰撞检测标志返回到由碰撞标志指向的变量中。
uart_set_wakeup_threshold设置浅睡眠唤醒的 RX 引脚信号边沿数
uart_get_wakeup_threshold获取浅睡眠唤醒的 RX 引脚信号边沿数
uart_wait_tx_idle_polling等到 UART tx 内存为空并且最后一个字符发送正常(轮询模式)
uart_set_loop_back配置TX信号环回RX模块,仅供测试使用
uart_set_always_rx_timeout配置 UART RX 超时中断的行为

五、报错:

问题一:

uart: uart_read_bytes(1156): uart driver error

解决:
没有初始化该串口,初始化一下


问题二:

uart: uart_driver_install(1284): uart tx buffer length error(>128 or 0)

解决:
发送缓冲区太小。应 >128 or 0
注:Rx_buffer_size 应该大于 UART_FIFO_LEN。Tx_buffer_size 应为零或大于 UART_FIFO_LEN


问题三:

Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled

uart_driver_install函数:

#define UART_FULL_THRESH_DEFAULT        (120)

uart_intr_config_t uart_intr = {
    .intr_enable_mask = UART_INTR_CONFIG_FLAG,
    .rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT,
    .rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
    .txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT,
};

默认值 120,只能接收到120个字节就中断。

### 回答1: 首先,需要在ESP32上安装MicroPython固件。然后我们可以使用uPyCraft或者其他类似的IDE来编写并上传代码。 以下是一个示例代码,用于ESP32上基于MicroPython的UART串口通信: ```python import machine import time # 配置UART的引脚以及波特率 uart = machine.UART(2, baudrate=115200) while True: if uart.any(): # 读取串口接收的数据 data = uart.read() print(data) # 发送数据到串口 uart.write("Hello World!\n") time.sleep(1) ``` 在这个示例中,我们首先导入了`machine`和`time`模块。`machine.UART()`函数用来创建一个UART对象,并指定其引脚和波特率。在上面的代码中,我们使用了引脚2作为UART引脚,并将波特率设置为115200。 然后,在一个无限循环中,我们通过`uart.any()`函数检查串口是否有数据可供接收。如果有数据,我们使用`uart.read()`函数读取数据,并使用`print()`函数将数据打印出来。 接着,我们使用`uart.write()`函数向串口发送数据。在上面的代码中,我们发送了"Hello World!\n"这个字符串。 最后,我们使用`time.sleep(1)`函数使代码暂停1秒钟,然后继续下一个循环。 这样,我们就可以在ESP32上实现基于MicroPython的UART串口通信了。注意,以上代码仅作为示例,请根据实际需求进行相应的修改。 ### 回答2: 在以下是ESP32UART串口通信的基于MicroPython的示例代码: 1. 引入必要的库: ```python import machine import time ``` 2. 配置UART串口: ```python uart = machine.UART(1, baudrate=115200) ``` 3. 发送数据: ```python uart.write('Hello, World!') ``` 4. 接收数据: ```python data = uart.read() if data: print(str(data)) ``` 5. 循环接收和发送数据: ```python while True: if uart.any(): data_received = uart.read() print(str(data_received)) time.sleep(1) uart.write('This is a test message.') time.sleep(1) ``` 以上是ESP32UART串口通信的基于MicroPython的示例代码,通过这些代码可以实现UART串口的发送和接收数据的功能。当然,这只是示例代码的一部分,在实际应用场景中,您可能需要根据具体的需求进行适当的修改和扩展。希望能对您有所帮助! ### 回答3: ESP32是一款内置WiFi和蓝牙功能的微控制器,可以通过串口通信实现与其他设备的数据交互。以下是基于MicroPython实现的ESP32串口通信的示例代码: 首先,需要导入ESP32UART模块和时间模块,用于控制串口和延时: ``` from machine import UART import utime ``` 接下来,需要配置UART的参数,例如波特率、数据位、停止位和校验位,以及定义接收/发送缓冲区的大小: ``` uart = UART(1, baudrate=9600, bits=8, parity=None, stop=1, tx=17, rx=16, timeout=1000) ``` 其中,"1"表示UART1,波特率设置为9600,数据位设置为8位,无校验位,停止位设置为1位,tx和rx分别设置为GPIO17和GPIO16作为发送和接收引脚,timeout设置为1000毫秒。 然后,可以使用uart.read()函数从串口接收数据,并将其打印出来: ``` data = uart.read() if data is not None: print(data.decode('utf-8')) ``` 这段代码会不断检测串口是否有数据到达,然后将数据转换为UTF-8编码并打印出来。 如果想要发送数据到串口,可以使用uart.write()函数: ``` uart.write('Hello ESP32!') ``` 这段代码会向串口发送字符串"Hello ESP32!"。 最后,如果不再需要使用串口,可以使用uart.deinit()函数关闭串口: ``` uart.deinit() ``` 这是基于MicroPython的ESP32串口通信的示例代码,通过配置UART参数、接收和发送数据,可以实现与其他设备的串口通信
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值