Skip to content

概念先知道

  • 红外遥控:用载波调制把“0/1”编码成红外光脉冲,接收头再把光转回电信号。
  • NEC 协议:最常见的红外编码协议,一帧 32 位 = 地址码 + 地址反码 + 命令码 + 命令反码。
  • 接收/发送:BL616/BL618 例程以接收为主(TEST_IR_RX),发送仅在 BL618DG 等芯片上编译。

例程功能简介

本页对应博流官方 SDK 的 ir_nec 例程(examples/peripherals/ir/ir_nec),演示红外 NEC 协议接收:

  • 初始化红外接收外设(bflb_ir_rx_init,NEC 模式),使能接收后阻塞等待;
  • 收到一帧 NEC 数据后打印位数与 32 位数据值;
  • BL618DG 等芯片还支持红外发送(TEST_IR_TX),可两块开发板一收一发做回环测试。
  • 同族例程examples/peripherals/ir/):ir_rc5(RC5 协议)、ir_swm / ir_swm_int(软件协议/中断)。

操作步骤

1
硬件准备

BL616/BL618 例程以接收模式为主(TEST_IR_RX):把红外接收头接到开发板 IR RX 引脚(见 board_ir_gpio_init()),VCC 接 3.3V、GND 接 GND。准备一个 NEC 协议的红外遥控器。

2
进入例程目录

在终端进入 SDK 的 IR 例程目录(前提:已按快速开始(Linux)Windows搭建好环境):

cd examples/peripherals/ir/ir_nec
3
编译工程

执行编译命令。Ai-M62(BL616)与 Ai-M61(BL618)同属一个系列,统一填写引脚最少的 bl616 即可:

make CHIP=bl616 BOARD=bl616dk
4
烧录固件

用 USB 线连接开发板,按住 BOOT 键(Ai-M61-32S-Kit 为 IO2)不放、短按 EN/RST 进入下载模式,然后执行烧录(把串口号换成实际值):

make flash CHIP=bl616 COMX=/dev/ttyUSB0
5
运行验证

打开串口助手(波特率 2000000)。用红外遥控器对准接收头按下一个按键,串口会打印 Receive bit: 32, value: 0x...,即收到的 NEC 码(32 位)。

代码执行流程

例程从启动到运行的完整流程如下(图中的循环箭头表示反复执行):

例程调用的 API 介绍

bflb_device_get_by_name("irrx")

获取红外接收外设的设备句柄(发送端为 "irtx")。

参数

  • name:外设名称,"irrx" 接收 / "irtx" 发送

返回值struct bflb_device_s * 设备句柄

bflb_ir_rx_init(irrx, config)

初始化红外接收。struct bflb_ir_rx_config_s 中:rx_mode = IR_RX_NEC(NEC 协议)、input_inverse = true(接收头输出反相)、deglitch_enable = false

参数

  • irrx:接收设备句柄
  • config:配置结构体指针

返回值:成功返回 0;失败返回负值错误码

bflb_ir_rx_enable(irrx, true)

使能/关闭红外接收。

参数

  • irrx:接收设备句柄
  • enabletrue 使能 / false 关闭

返回值:无

bflb_ir_receive(irrx, &rx_data)

阻塞接收一帧红外数据。

参数

  • irrx:接收设备句柄
  • rx_datauint64_t * 输出接收到的数据

返回值:接收到的有效位数(NEC 为 32)

完整代码

以下为 ir_nec/main.c 完整源码,与官方示例(examples/peripherals/ir/ir_nec)一致;点灯引脚已适配 Ai-M61/62-32S-Kit 板载 RGB 灯,默认折叠,点击展开:

📜 点击展开 ir_nec/main.c 完整代码
c
#include "bflb_ir.h"
#include "board.h"

#if defined(BL602) || defined(BL702) || defined(BL702L) || defined(BL618DG)
#define TEST_IR_TX
#endif

#if defined(BL602) || defined(BL702) || defined(BL616) || defined(BL618DG) || defined(BL616CL)
#define TEST_IR_RX
#endif

#ifdef TEST_IR_TX
struct bflb_device_s *irtx;
#endif
#ifdef TEST_IR_RX
struct bflb_device_s *irrx;
#endif

/* main */
int main(void)
{
    board_init();

    printf("IR NEC case:\r\n");

    board_ir_gpio_init();

#ifdef TEST_IR_TX
    uint32_t tx_buffer[1] = { 0xE916FF00 };
    struct bflb_ir_tx_config_s tx_cfg;

    irtx = bflb_device_get_by_name("irtx");

    /* TX init */
    tx_cfg.tx_mode = IR_TX_NEC;
    bflb_ir_tx_init(irtx, &tx_cfg);
#endif

#ifdef TEST_IR_RX
    uint64_t rx_data;
    uint8_t rx_len;
    struct bflb_ir_rx_config_s rx_cfg;

    irrx = bflb_device_get_by_name("irrx");

    /* RX init */
    rx_cfg.rx_mode = IR_RX_NEC;
    rx_cfg.input_inverse = true;
    rx_cfg.deglitch_enable = false;
    bflb_ir_rx_init(irrx, &rx_cfg);

    /* Enable rx, wait for sending */
    bflb_ir_rx_enable(irrx, true);
#endif

#ifdef TEST_IR_TX
    /* Send */
    bflb_ir_send(irtx, tx_buffer, 1);
    printf("Send 0x%08lx\r\n", tx_buffer[0]);
#endif

#ifdef TEST_IR_RX
    /* Receive */
    rx_len = bflb_ir_receive(irrx, &rx_data);

#ifdef TEST_IR_TX
    /* Check data received */
    if (rx_data != tx_buffer[0]) {
        printf("Data error! receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data);
    } else {
        printf("Received correctly. receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data);
    }
#else
    printf("Receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data);
#endif
#endif

    printf("end\r\n");

    while (1) {
    }
}

FAQ

遥控器按键后没有打印

确认接收头接线(信号脚接对、VCC 3.3V、共地)且遥控器为 NEC 协议;部分遥控器是 RC5/RC6 等其他协议,例程只解析 NEC。

打印的 value 与按键不符

NEC 码包含地址码+命令码+反码,不同遥控器映射不同;关注相对稳定即可,或换用已知 NEC 码值的遥控器验证。

想测试发送功能

发送仅在 BL618DG 等芯片上编译(TEST_IR_TX);标准 Ai-M61/62 模组(BL616/BL618)例程只启用接收。

相关最佳实践

遇到问题?

如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23