IC:

支持的芯片

Ameba SoC

RTL8721Dx

RTL8720E

RTL8726E

RTL8713E

RTL8730E

RTL8721F

支持状态

Y

N

N

N

Y

Y

概述

红外辐射(Infrared Radition, IR)模块是一个红外发送和接收控制器。该模块提供了用于红外辐射发送的硬件调制功能,以及用于接收的硬件自动捕获功能,支持半双工通信。

本章将介绍如何使用该红外辐射模块。

工作原理

红外模块支持硬件调制,可用于 TX 端信号发送。

同时,该模块能够检测连续高/低电平信号的周期,并将其记录到 RX FIFO 中,之后由软件对接收到的红外信号序列进行识别和处理。

为简化红外信号模型,将一系列红外信号划分为以下几类符号:

  • 载波符号:在一定时间内包含若干载波时钟周期的信号。

  • 空间符号:在一定时间内保持连续高电平或低电平的信号。

其中,载波符号是在物理介质中实际传播的调制信号;空间符号则代表调制前或解调后的数字信号。

../../rst_rtos/8_ir/figures/ir_signal_model.svg

IR 信号模型

工作模式

IR 模块支持发送与接收两种工作模式,进行完整的红外通信链路建立。

红外模块工作模式如下表所示:

工作模式

核心功能

技术特征

信号链路特征

发送模式

红外信号生成与调制

支持载波参数可编程控制

数字信号 → 载波调制 → 红外发射

接收模式

红外信号捕获与解调

兼容两种接收前端架构

红外信号 → 基带恢复 → 数字解码

发送模式

在发送模式下,软件通过配置参数为红外模块设置一定频率的载波信号。 同时,软件还需向 TX FIFO 写入数据,用于控制空间符号中高/低电平信号的持续时间,从而实现红外信号的正确调制与发射。

../../rst_rtos/8_ir/figures/ir_tx_flow.svg

TX 工作流程示意图

如何解析 TX FIFO 中的数据

TX FIFO 的数据为 32 位宽,包含以下信息:

字段

描述

参数含义

BIT[31]

是否发送载波

1:发送

0:不发送

BIT[30]

数据发送结束标志

1:最后一笔包

0:正常包

BIT[29:28]

补偿模式

0:不发送载波阶段,用系统时钟计算周期数

3:不发送载波阶段,使用指定的补偿频率计算周期数

1,2:不建议使用

BIT[27:0]

载波/无载波的周期数

按载波频率或补偿频率计数

其中,字段 BIT[27:0] 计算方式:

BIT[27:0] = fcarrier * Tduration

参数含义:

fcarrier:

载波频率(单位:赫兹)

Tduration:

载波或无载波符号的持续时间(单位:秒)

备注

  • 补偿机制:仅对 TX 计数 无载波阶段 有效

  • 补偿模式:不建议使用 mode1, mode2

下面以 NEC 编码协议,38kHZ 的载波频率,补偿模式为 0 的设定为例,介绍如何组织写入 TX FIFO 的数据。

NEC 编码协议简介

NEC 编码协议格式由 2 个起始符号、64 个数据符号和 1 个停止符号组成。其中,

  • 逻辑 1: 由 560us 的高电平信号与 (2250-560)us 的低电平信号构成

  • 逻辑 0: 由 560us 的高电平信号与 (1120-560)us 的低电平信号构成

../../rst_rtos/8_ir/figures/ir_nec_protocol.svg

NEC 调制

如何组织发送到 TX FIFO 中的数据

  • 如果发送逻辑 1, 应该向 TX FIFO 写入以下两笔数据:

    :width: 100% :widths: auto

    Entry

    BIT[31]

    BIT[30]

    BIT[29:28]

    BIT[27:0]

    First

    1

    0

    0

    38 * 560 / 1000 = 21

    Second

    0

    0

    0

    38 * (1690 - 560) / 1000 = 63

  • 如果发送逻辑 0, 应该向 TX FIFO 写入以下两笔数据:

    :width: 100% :widths: auto

    Entry

    BIT[31]

    BIT[30]

    BIT[29:28]

    BIT[27:0]

    First

    1

    0

    0

    38 * 560 / 1000 = 21

    Second

    0

    0

    0

    38 * (1120 - 560) / 1000 = 21

  • 如果发送停止符号

    停止符号为向 TX FIFO 中写入的最后一包数据,因此应设置 BIT[30]=1, 表示停止数据传输,当前这一笔仍会发出。

    :width: 100% :widths: auto

    Entry

    BIT[31]

    BIT[30]

    BIT[29:28]

    BIT[27:0]

    First

    1

    1

    0

    38 * 560 / 1000 = 21

接收模式

IR 接收模块支持 学习模式普通接收模式 两种工作方式,分别对应 红外二极管红外接收模块 作为硬件前端。

  • 使用红外二极管时:RX 输入信号中包含载波,IR 内核捕获的是载波符号,需由软件完成解调与解码,提取载波频率和占空比等信息。

  • 使用红外接收模块时:载波已由前端滤除,IR 内核捕获的是空间符号,无需软件解调,便于后续解析处理。

../../rst_rtos/8_ir/figures/ir_rx_modules.svg

RX 工作流程示意图——红外接收模块与红外二极管前端对比

如何解析 RX FIFO 中的数据

RX FIFO 的数据为 32 位宽,包含以下两部分信息:

字段

描述

参数含义

BIT[31]

接收到信号的电平状态

  • 1:高电平

  • 0:低电平

BIT[30:0]

信号在当前电平状态下,持续的采样时钟周期数

与采样频率有关

例如,在采样率为 10MHz(时钟周期为 100ns)的条件下:

数据

RX FIFO 值

含义

Data 1

0X10001000

表示检测到约 409.6 μs 的高电平信号

Data 2

0X00A1644

表示检测到约 66.106 ms 的低电平信号

开始接收的条件

  • 手动接收: 允许手动控制接收过程。

  • 自动接收:

    • 触发条件配置:

      • 上升沿、下降沿或任何信号变化

    • 功能:

      • 软件设置上述条件以启动自动接收

    • 操作:

      • 在 RX 输入信号检测到配置的触发器时,硬件会自动开始接收过程

  • 数据处理:

    • 红外内核捕获的内容:

      • 信号电平: 信号的状态(高电平或低电平)

      • 持续时间: 信号保持在特定电平状态的时钟周期数

    • 存储:

      • 捕获的内容存储在 RX FIFO 中,供软件进一步处理

停止接收的条件

IR RX 模块会根据软件的设定,当输入信号满足触发特定中断事件的条件后,由软件在中断处理函数中关闭 IR,停止接收。

相关设定如下:

a. 停止接收时的输入信号电平状态
b. 上述电平状态的持续时间
c. 使能 RX Counter 阈值中断

上述中断事件的上报条件为:

当 RX FIFO 中数据的电平状态与软件设定的停止条件一致,且该状态的持续时间达到预设阈值时,会产生 IR_BIT_RX_CNT_THR_INT_STATUS 中断。

例如,对于如下配置,在 RX 模块检测到输入信号为 低电平状态 ,并且其 持续时间不小于约 66.1ms 时会产生该中断事件。

      /* 10MHz 的采样率 */
IR_InitStruct.IR_Freq = 10000000;

      /* 条件 1:电平信号状态 */
IR_InitStruct.IR_RxCntThrType = IR_RX_COUNT_LOW_LEVEL;

      /* 条件 2:电平信号持续时间的阈值,设置为 66.1ms 左右 */
IR_InitStruct.IR_RxCntThr = 0xa1644;

      /* 条件 3:使能 RX Counter 阈值中断 */
IR_INTConfig(IR_DEV, IR_BIT_RX_CNT_THR_INT_EN, ENABLE);

模式设定示例

IR 发送模式

 /* step1: 配置作为 TX 信号输出的 Pin 脚, 如选用 PB4 */
 Pinmux_Config(_PB_4, PINMUX_FUNCTION_IR_TX);

 /* step2: 禁用 IR 模块 */
 IR_Cmd(IR_DEV, IR_MODE_TX, DISABLE);

 /* step3: 初始化结构体,用于设定模块工作参数 */
 IR_StructInit(&IR_InitStruct);
 IR_InitStruct.IR_Clock = IR_CLOCK_HZ;
 IR_InitStruct.IR_Mode = IR_MODE_TX;
 IR_InitStruct.IR_Freq = 38000;

 /* step4: 将 step3 的结构体信息写入 IR 模块寄存器 */
 IR_Init(IR_DEV, &IR_InitStruct);

 /* step5: 将待发送数据写入 FIFO */
 IR_SendBuf(IR_DEV, pBuf, txlen, FALSE);

 /*step6: 启用 IR 功能,开始传输数据*/
 IR_Cmd(IR_DEV, IR_MODE_TX, ENABLE);

 /* step7: 根据需要来决定是否向 TX FIFO 写入更多数据 */
 while (txlen_remaining == 0) {
     /* 处理待发送数据 */
     {
           /*
              do something
           */
     }
     IR_SendBuf(IR_DEV, pBuf, txlen, IsLastPacket);
 }

 /* step8: 发送完成,禁用 IR */
 IR_Cmd(IR_DEV, IR_MODE_TX, DISABLE);

备注

  • 确认 TX FIFO 中数据已发送完毕的条件:如果想判断 TX FIFO 中的数据是否全部发出,应轮询寄存器 IR_TX_SR 的状态位 IR_BIT_TX_FIFO_EMPTY 是否有被置位,该值为 1 表明发送完毕。

  • 在使能 IR TX 之前,建议先向 TX FIFO 写入一些数据包,如 step 5~6 所示。同时,软件应及时向 TX FIFO 写入数据,避免 TX FIFO 中出现断流的情况。

IR 接收模式

/* step1: 配置作为 RX 信号输入的 Pin 脚, 如选用 PB4 */
Pinmux_Config(_PB_4, PINMUX_FUNCTION_IR_RX);

/* step2: 禁用 IR 模块 */
IR_Cmd(IR_DEV, IR_MODE_RX, DISABLE);

/* step3: 初始化结构体,用于设定模块工作参数 */
IR_StructInit(&IR_InitStruct);
IR_InitStruct.IR_Clock = IR_CLOCK_HZ;
IR_InitStruct.IR_Mode = IR_MODE_RX;
IR_InitStruct.IR_Freq = 10000000; //sample frequency :Hz
IR_InitStruct.IR_RxCntThrType = IR_RX_COUNT_LOW_LEVEL;
IR_InitStruct.IR_RxCntThr = 0xa1644;//66ms

/* step4: 将 step3 的结构体信息写入 IR 模块寄存器 */
IR_Init(IR_DEV, &IR_InitStruct);

/* step5: 注册中断处理函数,并使能 NVIC 中断 */
InterruptRegister((IRQ_FUN)IR_irq_handler, IR_IRQ, (u32)NULL, IR_IRQ_PRIORITY_TEST);
InterruptEn(IR_IRQ, IR_IRQ_PRIORITY_TEST);

/* step6: 使能模块中断 */
IR_INTConfig(IR_DEV, IR_RX_INT_ALL_EN, ENABLE);

/* step7: 启用 IR 功能,开始接收数据*/
IR_Cmd(IR_DEV, IR_MODE_RX, ENABLE);

/* step8: 响应中断事件 */
void IR_irq_handler(void)
{
    /* 获取中断状态 */
    IntStatus = IR_GetINTStatus(IR_DEV);

    /* 清除中断状态 */
    IR_ClearINTPendingBit(IR_DEV, IntStatus);

    /* RX FIFO 中收到数据的数目达到预设的阈值,则将数据从 FIFO 读至内存中,以便后续处理 */
    if (IntStatus & IR_BIT_RX_FIFO_LEVEL_INT_STATUS) {
        IR_RX_recv();
    }

    /* 识别到接收结束标志,关闭 IR */
    if (IntStatus & IR_BIT_RX_CNT_THR_INT_STATUS) {
        IR_Cmd(IR_DEV, IR_MODE_RX, DISABLE);
    }
}