支持的芯片
Ameba SoC |
RTL8721Dx |
RTL8720E |
RTL8726E |
RTL8713E |
RTL8730E |
RTL8721F |
---|---|---|---|---|---|---|
支持状态 |
Y |
N |
N |
N |
Y |
Y |
概述
红外辐射(Infrared Radition, IR)模块是一个红外发送和接收控制器。该模块提供了用于红外辐射发送的硬件调制功能,以及用于接收的硬件自动捕获功能,支持半双工通信。
本章将介绍如何使用该红外辐射模块。
工作原理
红外模块支持硬件调制,可用于 TX 端信号发送。
同时,该模块能够检测连续高/低电平信号的周期,并将其记录到 RX FIFO 中,之后由软件对接收到的红外信号序列进行识别和处理。
为简化红外信号模型,将一系列红外信号划分为以下几类符号:
载波符号:在一定时间内包含若干载波时钟周期的信号。
空间符号:在一定时间内保持连续高电平或低电平的信号。
其中,载波符号是在物理介质中实际传播的调制信号;空间符号则代表调制前或解调后的数字信号。
IR 信号模型
工作模式
IR 模块支持发送与接收两种工作模式,进行完整的红外通信链路建立。
红外模块工作模式如下表所示:
工作模式 |
核心功能 |
技术特征 |
信号链路特征 |
---|---|---|---|
发送模式 |
红外信号生成与调制 |
支持载波参数可编程控制 |
数字信号 → 载波调制 → 红外发射 |
接收模式 |
红外信号捕获与解调 |
兼容两种接收前端架构 |
红外信号 → 基带恢复 → 数字解码 |
发送模式
在发送模式下,软件通过配置参数为红外模块设置一定频率的载波信号。 同时,软件还需向 TX FIFO 写入数据,用于控制空间符号中高/低电平信号的持续时间,从而实现红外信号的正确调制与发射。
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 的低电平信号构成
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 内核捕获的是空间符号,无需软件解调,便于后续解析处理。
RX 工作流程示意图——红外接收模块与红外二极管前端对比
如何解析 RX FIFO 中的数据
RX FIFO 的数据为 32 位宽,包含以下两部分信息:
字段 |
描述 |
参数含义 |
---|---|---|
BIT[31] |
接收到信号的电平状态 |
|
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);
}
}