概念先知道
- UART(串口):像“电报线”,一字节一字节地传数据,收发各一根线(TX/RX)。
- 波特率:每秒传输的位数,例程 2000000(2M)——收发两端必须设成一样,否则乱码。
- 8N1:8 个数据位 + 无校验(None)+ 1 个停止位,串口最常见的参数组合。
- FIFO 中断:数据攒到一定数量(阈值)再通知 CPU,减少频繁打断,适合高速通信。
例程功能简介
本页对应博流官方 SDK 的 uart_fifo_interrupt 例程(examples/peripherals/uart/uart_fifo_interrupt),演示 UART 的 FIFO 中断收发:
- 串口参数:波特率 2000000、8 位数据、1 位停止位、无校验(8N1);
- 发送方向:发送 FIFO 中断触发时发送 27 个测试字节(0x00~0x1A);
- 接收方向:接收 FIFO 中断与超时中断(RTO)把收到的数据存入缓冲区,主循环以十六进制
0xXX打印。 - 同族例程(
examples/peripherals/uart/):uart_poll(轮询收发)、uart_dma(DMA 收发)、uart_cts(硬件流控)、uart_sw_rts(软件 RTS)、uart_rs485(RS485)、uart_lin(LIN)、uart_auto_baudrate(自适应波特率)、uart_ir(红外载波)、uart_end_interrupt/uart_error_interrupt/uart_dma_rto/uart_feature_control(中断与特性测试)。
操作步骤
使用开发板自带的 USB 串口(默认测试串口 DEFAULT_TEST_UART 由板级配置决定,通常是 uart0),不需要额外接线,用数据线连接电脑即可。
在终端进入 SDK 的 UART 例程目录(前提:已按快速开始(Linux)或Windows搭建好环境):
cd examples/peripherals/uart/uart_fifo_interrupt执行编译命令。Ai-M62(BL616)与 Ai-M61(BL618)同属一个系列,统一填写引脚最少的 bl616 即可:
make CHIP=bl616 BOARD=bl616dk用 USB 线连接开发板,按住 BOOT 键(Ai-M61-32S-Kit 为 IO2)不放、短按 EN/RST 进入下载模式,然后执行烧录(把串口号换成实际值):
make flash CHIP=bl616 COMX=/dev/ttyUSB0打开串口助手(波特率 2000000)。例程启动后会先通过发送 FIFO 中断发送 0x00~0x1A 共 27 个字节并打印 tx fifo;之后你在串口助手发送任意数据,都会被接收并以 0xXX 十六进制格式打印出来。
代码执行流程
例程从启动到运行的完整流程如下(图中的循环箭头表示反复执行):
例程调用的 API 介绍
bflb_uart_init(uart, config)
按配置初始化串口。struct bflb_uart_config_s 中:
baudrate:波特率,例程2000000data_bits:数据位,UART_DATA_BITS_8stop_bits:停止位,UART_STOP_BITS_1parity:校验,UART_PARITY_NONEtx_fifo_threshold/rx_fifo_threshold:FIFO 中断阈值,例程7bit_order:位序,UART_LSB_FIRST
参数:
uart:串口设备句柄(bflb_device_get_by_name(DEFAULT_TEST_UART))config:配置结构体指针
返回值:成功返回 0;失败返回负值错误码
bflb_uart_get_intstatus(uart)
在中断回调中读取中断状态,判断是哪种事件触发。
参数:
uart:串口设备句柄
返回值:中断状态位,常用 UART_INTSTS_RX_FIFO(接收 FIFO)、UART_INTSTS_RTO(接收超时)、UART_INTSTS_TX_FIFO(发送 FIFO)
bflb_uart_txint_mask / bflb_uart_rxint_mask(uart, mask)
屏蔽/取消屏蔽发送、接收中断:false 取消屏蔽(使能中断),true 屏蔽。
参数:
uart:串口设备句柄mask:false使能 /true屏蔽
返回值:无
完整代码
以下为 uart_fifo_interrupt/main.c 完整源码,与官方示例(examples/peripherals/uart/uart_fifo_interrupt)一致;点灯引脚已适配 Ai-M61/62-32S-Kit 板载 RGB 灯,默认折叠,点击展开:
📜 点击展开 uart_fifo_interrupt/main.c 完整代码
#include "bflb_mtimer.h"
#include "bflb_uart.h"
#include "board.h"
struct bflb_device_s *uartx;
#define RX_BUFF_SIZE 1024
static uint8_t uart_txbuf[128] = { 0 };
static uint8_t uart_rxbuf[RX_BUFF_SIZE] = { 0 };
static uint32_t uart_rx_count = 0;
void uart_isr(int irq, void *arg)
{
uint32_t intstatus = bflb_uart_get_intstatus(uartx);
if (intstatus & UART_INTSTS_RX_FIFO) {
while (bflb_uart_rxavailable(uartx)) {
uart_rxbuf[uart_rx_count++] = bflb_uart_getchar(uartx);
}
}
if (intstatus & UART_INTSTS_RTO) {
bflb_uart_int_clear(uartx, UART_INTCLR_RTO);
printf("rto\r\n");
while (bflb_uart_rxavailable(uartx)) {
uart_rxbuf[uart_rx_count++] = bflb_uart_getchar(uartx);
}
}
if (intstatus & UART_INTSTS_TX_FIFO) {
printf("tx fifo\r\n");
for (uint8_t i = 0; i < 27; i++) {
bflb_uart_putchar(uartx, uart_txbuf[i]);
}
bflb_uart_txint_mask(uartx, true);
}
}
int main(void)
{
board_init();
board_uartx_gpio_init();
uartx = bflb_device_get_by_name(DEFAULT_TEST_UART);
for (uint8_t i = 0; i < 128; i++) {
uart_txbuf[i] = i;
}
struct bflb_uart_config_s cfg;
cfg.baudrate = 2000000;
cfg.data_bits = UART_DATA_BITS_8;
cfg.stop_bits = UART_STOP_BITS_1;
cfg.parity = UART_PARITY_NONE;
cfg.flow_ctrl = 0;
cfg.tx_fifo_threshold = 7;
cfg.rx_fifo_threshold = 7;
cfg.bit_order = UART_LSB_FIRST;
bflb_uart_init(uartx, &cfg);
bflb_uart_txint_mask(uartx, false);
bflb_uart_rxint_mask(uartx, false);
bflb_irq_attach(uartx->irq_num, uart_isr, NULL);
bflb_irq_enable(uartx->irq_num);
while (1) {
if (uart_rx_count > RX_BUFF_SIZE) {
uart_rx_count = RX_BUFF_SIZE;
}
if (uart_rx_count) {
for (uint32_t i = 0; i < uart_rx_count; i++) {
printf("0x%02x\r\n", uart_rxbuf[i]);
}
uart_rx_count = 0;
}
bflb_mtimer_delay_ms(100);
}
}FAQ
串口没有输出
波特率要设为 2000000;确认连接的是默认测试串口对应的 USB 口;如果烧录后无反应,先按一下复位键。
发送数据没有回显 0xXX
确认串口助手发送的是字符/HEX 且与例程接收端一致;例程把收到的每个字节以十六进制打印,一个字节对应一行 0xXX。
波特率可以改吗
可以。修改 cfg.baudrate 后重新编译烧录,并把串口助手波特率改成相同值即可;注意收发双方必须一致。
相关最佳实践
遇到问题?
如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

