You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在树莓派Pico(C/C++ SDK)中轮询检查串口数据?

树莓派Pico串口非阻塞轮询方法

当然有可行的轮询方案,核心是利用Pico SDK提供的非阻塞串口状态检查函数,或者直接操作硬件寄存器判断是否有数据可读。以下是两种常用实现方式:

方法一:使用Pico SDK封装的非阻塞检查函数

Pico SDK提供的uart_is_read_ready()函数会立即返回串口接收FIFO中是否有可用数据,完全不会阻塞程序执行,是最便捷的轮询方式。

示例代码

#include "pico/stdlib.h"

#define UART_INSTANCE uart0
#define BAUD_RATE 115200
#define TX_GPIO 0
#define RX_GPIO 1

int main() {
    // 初始化串口
    uart_init(UART_INSTANCE, BAUD_RATE);
    gpio_set_function(TX_GPIO, GPIO_FUNC_UART);
    gpio_set_function(RX_GPIO, GPIO_FUNC_UART);
    uart_set_format(UART_INSTANCE, 8, 1, UART_PARITY_NONE); // 8位数据、1位停止位、无校验

    while (true) {
        // 轮询检查是否有数据可读
        if (uart_is_read_ready(UART_INSTANCE)) {
            // 读取单个字节(非阻塞,已确认有数据)
            uint8_t received_byte = uart_getc(UART_INSTANCE);
            // 这里添加数据处理逻辑,比如回显到串口
            uart_putc(UART_INSTANCE, received_byte);
        }

        // 执行其他任务,比如控制GPIO、读取传感器等
        sleep_ms(5);
    }
}

若需批量读取多个字节,可结合uart_get_read_count()获取当前FIFO中的可用字节数:

if (uart_is_read_ready(UART_INSTANCE)) {
    uint32_t available_bytes = uart_get_read_count(UART_INSTANCE);
    uint8_t buffer[64];
    // 读取所有可用字节(此时uart_read_blocking不会阻塞,数据已存在)
    uint32_t read_bytes = uart_read_blocking(UART_INSTANCE, buffer, available_bytes);
    
    // 处理buffer中的数据,比如转发回串口
    uart_write_blocking(UART_INSTANCE, buffer, read_bytes);
}

方法二:直接操作UART硬件寄存器(底层实现)

如果追求极致性能,可直接检查UART线路状态寄存器(LSR)的数据就绪位(DR):

#include "hardware/uart.h"
#include "pico/stdlib.h"

#define UART_INSTANCE uart0
#define BAUD_RATE 115200
#define TX_GPIO 0
#define RX_GPIO 1

int main() {
    uart_init(UART_INSTANCE, BAUD_RATE);
    gpio_set_function(TX_GPIO, GPIO_FUNC_UART);
    gpio_set_function(RX_GPIO, GPIO_FUNC_UART);

    while (true) {
        // 检查LSR寄存器的DR位(Data Ready)
        if (uart_get_hw(UART_INSTANCE)->lsr & UART_LSR_DR_BITS) {
            uint8_t received_byte = uart_getc(UART_INSTANCE);
            // 处理数据
        }

        // 其他任务逻辑
        sleep_ms(5);
    }
}

注意事项

  • 优先使用SDK封装的uart_is_read_ready(),代码可读性更高,无需关心硬件寄存器细节;
  • 提前用uart_is_read_ready()确认有数据后,uart_read_blocking()不会触发阻塞;
  • 轮询间隔可按需调整:间隔过短会占用更多CPU资源,过长可能导致数据处理延迟。

内容的提问来源于stack exchange,提问作者Yatin Goyal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 09:47:57