IR Transmit
该示例演示 IR 发送功能的使用方法。
使用 IR 外设通过中断的形式进行较大数量的数据发送,实现红外发射功能,可使用逻辑分析仪观察 IR 发送波形。
环境需求
该示例的环境需求,可参考 环境需求。
硬件连线
连接 IR 发送引脚 P2_5 至逻辑分析仪。
配置选项
可配置如下宏修改引脚定义。
#define IR_TX_PIN P2_5
可配置如下宏修改设定的阈值。
#define IR_TX_FIFO_THR_LEVEL 2
编译和下载
该示例的编译和下载流程,可参考 编译和下载。
测试验证
在逻辑分析仪内观察 IR 发送波形。波形如下图所示。

IR 发送波形
代码介绍
该章节主要介绍示例中的初始化和相应功能实现的代码和流程说明。
源码路径
工程文件和源码路径如下:
工程路径:
sdk\samples\peripheral\ir\tx\proj
源码路径:
sdk\samples\peripheral\ir\tx\src
初始化
外设的初始化流程可参考 General Introduction 中的 初始化流程 部分。
调用
Pad_Config()
与Pinmux_Config()
,配置对应引脚的 PAD 和 PINMUX。void board_ir_init(void) { Pad_Config(IR_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW); Pinmux_Config(IR_TX_PIN, IRDA_TX); }
调用
RCC_PeriphClockCmd()
,开启 IR 时钟。对 IR 外设进行初始化:
定义
IR_InitTypeDef
类型IR_InitStruct
,调用IR_StructInit()
将IR_InitStruct
预填默认值。根据需求修改
IR_InitStruct
参数,IR 的初始化参数配置如下表。调用
IR_Init()
,初始化 IR 外设。
IR Hardware Parameters |
Setting in the |
IR |
---|---|---|
Sample Clock |
38000 |
|
IR Duty Cycle |
2 |
|
IR Mode |
||
IR Tx Threshold |
|
调用
IR_INTConfig()
,配置 IR 发送 FIFO 达到阈值中断IR_INT_TF_LEVEL
。配置 NVIC,详情参考参考 中断配置。
功能实现
IR 通过中断发送数据的流程如图所示:

IR 发送数据流程图
定义 IR 发送数据数组:有载波数据用载波个数与 0x80000000 进行或运算表示,无载波数据用载波个数与 0x00000000 进行或运算表示。
调用
IR_SendBuf()
函数,开始将发送数据加载到 IR TX FIFO 中。记录已经发送的数据个数
IR_TX_Count
。调用
IR_Cmd()
,使能 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 外设后,IR 开始发送数据。当 IR 发送 FIFO 数据个数小于设置的发送阈值(此例中设为 2)时,触发
IR_INT_TF_LEVEL
中断,进入中断处理函数。屏蔽
IR_INT_TF_LEVEL
中断。分批发送 IR 数据。
如果剩余待发送的数据个数大于发送 FIFO 的容量,说明仍有大量数据未发送。此时,需要向 IR 发送 FIFO 中加载
IR_TX_FIFO_SIZE - IR_TX_FIFO_THR_LEVEL
个数据并发送。如果剩余待发送的数据个数大于 0 但小于发送 FIFO 的容量,表示剩余的数据不多,当前可以将这些数据全部发送。这时,需要将剩余的数据全部加载到 IR 发送 FIFO 中。
否则,如果没有剩余数据,说明数据已全部发送完毕,失能
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); }