IR Transmit
该示例演示红外发送功能的使用方法。
使用 IR 外设进行数据发送,实现红外发射功能,使用逻辑分析仪观察IR发送波形。
环境需求
该示例支持以下开发套件:
Hardware Platforms |
Board Name |
---|---|
RTL87x2G HDK |
RTL87x2G EVB |
更多信息请参考快速入门。
硬件连线
连接IR发送引脚P2_5至逻辑分析仪。
编译和下载
该示例的工程路径如下:
Project file: samples\peripheral\ir\tx\proj\rtl87x2g\mdk
Project file: samples\peripheral\ir\tx\proj\rtl87x2g\gcc
请按照以下步骤操作构建并运行该示例:
打开工程文件。
按照 快速入门 中 编译APP Image 给出的步骤构建目标文件。
编译成功后,在路径
mdk\bin
或gcc\bin
下会生成 app binapp_MP_xxx.bin
文件。按下复位按键,开始运行。
测试验证
在逻辑分析仪内观察IR发送波形。波形如下图所示。

IR发送波形
代码介绍
该章节分为以下几个部分:
源码路径
工程路径:
sdk\samples\peripheral\ir\tx\proj
源码路径:
sdk\samples\peripheral\ir\tx\src
该工程的工程文件代码结构如下:
└── Project: tx
└── 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_TX功能。
driver_ir_init
包含了对IR外设的初始化。
使能PCC时钟。
设置IR发送频率为38kHz。
设置IR载波占空比为1/2。
设置IR为发送模式。
设置
IR_TxInverse
为IR_TX_DATA_NORMAL
,即不反转IR发送数据。设置IR发送FIFO阈值为2。
配置IR发送FIFO数据个数小于设置的发送阈值中断
IR_INT_TF_LEVEL
。
RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE);
...
IR_InitStruct.IR_Freq = vFreq;
IR_InitStruct.IR_DutyCycle = 2; /* !< 1/2 duty cycle */
IR_InitStruct.IR_Mode = IR_MODE_TX;
IR_InitStruct.IR_TxInverse = IR_TX_DATA_NORMAL;
IR_InitStruct.IR_TxFIFOThrLevel = IR_TX_FIFO_THR_LEVEL;
IR_Init(&IR_InitStruct);
/* Enable IR threshold interrupt. when TX FIFO offset <= threshold value, trigger interrupt*/
IR_INTConfig(IR_INT_TF_LEVEL, ENABLE);
...
功能实现
定义IR发送数据数组:有载波数据用载波个数与0x80000000进行或运算表示,无载波数据用载波个数与0x00000000进行或运算表示。
执行
IR_SendBuf()
函数,开始往IR发送FIFO中塞发送数据;使能IR外设发送功能。记录已经发送的数据个数。
IR_TxData.CarrierFreq = 38000;
IR_TxData.DataLen = 67 + 1; //2+64+1;
IR_TxData.DataBuf[0] = 0x80000000 | 0x156; //342 about 9ms
IR_TxData.DataBuf[1] = 0x00000000 | 0xAB; //171 about 4.5ms
...
IR_TxData.DataBuf[IR_TxData.DataLen - 1] = 0x80000000 | 0x15;
...
IR_SendBuf(IR_TxData.DataBuf, IR_TX_FIFO_SIZE, DISABLE);
IR_Cmd(IR_MODE_TX, ENABLE);
当IR发送FIFO数据个数小于设置的发送阈值(此例中设为2)时,触发
IR_INT_TF_LEVEL
中断,进入中断处理函数IR_Handler
。屏蔽
IR_INT_TF_LEVEL
中断。如果剩余发送数据个数大于发送FIFO大小,往IR发送FIFO中塞(IR_TX_FIFO_SIZE - IR_TX_FIFO_THR_LEVEL) 个数据并发送,清除
IR_INT_TF_LEVEL
中断挂起位。否则如果剩余发送数据个数大于0,往IR发送FIFO中塞剩余数据,清除
IR_INT_TF_LEVEL
中断挂起位。否则如果没有剩余数据,失能
IR_INT_TF_LEVEL
中断,清除IR_INT_TF_LEVEL
中断挂起位。取消屏蔽
IR_INT_TF_LEVEL
中断。
IR_MaskINTConfig(IR_INT_TF_LEVEL, ENABLE);
if ((IR_TxData.DataLen - IR_TX_Count) >= IR_TX_FIFO_SIZE)
{
IR_SendBuf(IR_TxData.DataBuf + IR_TX_Count, (IR_TX_FIFO_SIZE - IR_TX_FIFO_THR_LEVEL), DISABLE);
IR_TX_Count += (IR_TX_FIFO_SIZE - IR_TX_FIFO_THR_LEVEL);
/* Clear threshold interrupt */
IR_ClearINTPendingBit(IR_INT_TF_LEVEL_CLR);
}
else if ((IR_TxData.DataLen - IR_TX_Count) > 0)
{
/* The remaining data is less than the TX FIFO length */
/* Configure TX threshold level to zero and trigger interrupt when TX FIFO is empty */
IR_SetTxThreshold(0);
IR_SendBuf(IR_TxData.DataBuf + IR_TX_Count, IR_TxData.DataLen - IR_TX_Count, DISABLE);
IR_TX_Count += (IR_TxData.DataLen - IR_TX_Count);
/* Clear threshold interrupt */
IR_ClearINTPendingBit(IR_INT_TF_LEVEL_CLR);
}
else
{
/* Tx completed */
/* Disable IR tx empty interrupt */
IR_INTConfig(IR_INT_TF_LEVEL, DISABLE);
IR_TX_Count = 0;
/* Clear threshold interrupt */
IR_ClearINTPendingBit(IR_INT_TF_LEVEL_CLR);
}