IR Receive
该示例演示红外接收功能的使用方法。
使用另一颗EVB下载 IR 发送的程序作为IR数据的发送端向该EVB发送IR数据。
在IR中断内进行数据的接收,若数据量大于IR的FIFO,需要连续多次地接收数据。
IR发送端的示例可参考 IR Transmit 。
环境需求
该示例支持以下开发套件:
Hardware Platforms |
Board Name |
---|---|
RTL87x2G HDK |
RTL87x2G EVB |
更多信息请参考快速入门。
硬件连线
使用另一颗EVB下载IR TX程序,连接P2_5和另一颗EVB的发送引脚。
编译和下载
该示例的工程路径如下:
Project file: samples\peripheral\ir\rx\proj\rtl87x2g\mdk
Project file: samples\peripheral\ir\rx\proj\rtl87x2g\gcc
请按照以下步骤操作构建并运行该示例:
打开工程文件。
按照 快速入门 中 编译APP Image 给出的步骤构建目标文件。
编译成功后,在路径
mdk\bin
或gcc\bin
下会生成 app binapp_MP_xxx.bin
文件。按下复位按键,开始运行。
测试验证
当IR接收计数器的个数达到设置的阈值,代表IR数据接收完毕,进入IR中断,打印接收数据及其长度。接收的数据即为IR发送端定义的数据内容。
IR_INT_RX_CNT_THR
len = xx
[io_ir]io_handle_ir_msg: IR RX data[0] = xxx
[io_ir]io_handle_ir_msg: IR RX data[1] = xxx
...
代码介绍
该章节分为以下几个部分:
源码路径
工程路径:
sdk\samples\peripheral\ir\rx\proj
源码路径:
sdk\samples\peripheral\ir\rx\src
该工程的工程文件代码结构如下:
└── Project: rx
└── secure_only_app
└── Device includes startup code
├── startup_rtl.c
└── system_rtl.c
├── CMSIS includes CMSIS header files
├── CMSE Library Non-secure callable lib
├── Lib includes all binary symbol files that user application is built on
└── rtl87x2g_io.lib
├── Peripheral includes all peripheral drivers and module code used by the application
├── rtl_rcc.c
├── rtl_pinmux.c
├── rtl_nvic.c
└── rtl_ir.c
└── APP includes the ble_peripheral user application implementation
├── main_ns.c
└── io_ir.c
初始化
初始化流程包括了 board_ir_init
和 driver_ir_init
。
board_ir_init
包含了对PAD和PINMUX的设置。
配置PAD:设置引脚、PINMUX模式、PowerOn、无内部上拉。
配置PINMUX:分配引脚P2_5为IRDA_RX功能。
driver_ir_init
包含了对IR外设的初始化。
使能PCC时钟。
设置IR接收频率为38kHz。
设置IR为自动接收模式。
设置IR接收阈值为30,当IR接收FIFO满时丢弃最新数据,过滤低于50ns的杂波数据。
设置触发接收计数器阈值中断的电平类型为低电平,IR_RxCntThr设置为0x1400。
使能IR外设接收功能,清除IR接收FIFO。
配置IR接收FIFO数据个数大于设置的接收阈值中断
IR_INT_RF_LEVEL
和接收电平超时中断IR_INT_RX_CNT_THR
。取消屏蔽
IR_INT_RF_LEVEL
和IR_INT_RX_CNT_THR
中断。
RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
...
IR_InitStruct.IR_Freq = 38000;
IR_InitStruct.IR_Mode = IR_MODE_RX;
IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE;
IR_InitStruct.IR_RxFIFOThrLevel = IR_RX_FIFO_THR_LEVEL;
IR_InitStruct.IR_RxFIFOFullCtrl = IR_RX_FIFO_FULL_DISCARD_NEWEST;
IR_InitStruct.IR_RxFilterTime = IR_RX_FILTER_TIME_50ns;
IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;
IR_InitStruct.IR_RxCntThrType = IR_RX_Count_Low_Level;
IR_InitStruct.IR_RxCntThr = 0x200;
IR_Init(&IR_InitStruct);
IR_Cmd(IR_MODE_RX, ENABLE);
IR_ClearRxFIFO();
...
IR_INTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, ENABLE);
IR_MaskINTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, DISABLE);
功能实现
向IR收发模块发送IR数据。当IR接收FIFO的数据个数达到设置的接收阈值(此例中设为30)时,触发
IR_INT_RF_LEVEL
中断。或当接收计数器的个数达到设置的阈值(此例中设为0x1400)时,触发IR_INT_RX_CNT_THR
中断,进入中断处理函数IR_Handler
。屏蔽
IR_INT_TF_LEVEL
和IR_INT_RX_CNT_THR
中断。如果触发的中断为
IR_INT_TF_LEVEL
,则需要IR从FIFO中接收数据。将数据存入DataBuf内,并记录已经接收的数据长度。如果触发的中断为
IR_INT_RX_CNT_THR
,则代表触发了IR接收数据的停止条件。将剩余数据存入DataBuf内,记录已经接收的数据长度,并打印数据内容。清除
IR_INT_RX_CNT_THR
中断挂起位。取消屏蔽
IR_INT_RF_LEVEL
和IR_INT_RX_CNT_THR
中断。
if (int_status_rfl == SET)
{
len = IR_GetRxDataLen();
IR_ReceiveBuf(IR_Rx_Data.DataBuf + IR_RX_Count, len);
IR_Rx_Data.DataLen += len;
IR_RX_Count += len;
IR_ClearINTPendingBit(IR_INT_RF_LEVEL_CLR);
}
/* Stop to receive IR data */
if (int_status_rxcnt == SET)
{
DBG_DIRECT("IR_INT_RX_CNT_THR");
/* Read remaining data */
len = IR_GetRxDataLen();
IR_ReceiveBuf(IR_Rx_Data.DataBuf + IR_RX_Count, len);
IR_Rx_Data.DataLen += len;
IR_RX_Count += len;
DBG_DIRECT("len = %d", IR_RX_Count);
for (uint16_t i = 0; i < IR_RX_Count; i++)
{
DBG_DIRECT("[io_ir]io_handle_ir_msg: IR RX data[%d] = 0x%x", i, IR_Rx_Data.DataBuf[i]);
}
memset(&IR_Rx_Data, 0, sizeof(IR_Rx_Data));
IR_RX_Count = 0;
IR_ClearINTPendingBit(IR_INT_RX_CNT_THR_CLR);
}
/* Unmask IR all interrupt */
IR_MaskINTConfig(IR_INT_RF_LEVEL | IR_INT_RX_CNT_THR, DISABLE);