如何在树莓派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
相关产品推荐
相关产品推荐

