IR Transmit

该示例演示 IR 发送功能的使用方法。

使用 IR 外设通过中断的形式进行较大数量的数据发送,实现红外发射功能,可使用逻辑分析仪观察 IR 发送波形。

环境需求

该示例的环境需求,可参考 环境需求

硬件连线

连接 IR 发送引脚 P2_5 至逻辑分析仪。

配置选项

  1. 可配置如下宏修改引脚定义。

    #define IR_TX_PIN                   P2_5
    
  2. 可配置如下宏修改设定的阈值。

    #define IR_TX_FIFO_THR_LEVEL        2
    

编译和下载

该示例的编译和下载流程,可参考 编译和下载

测试验证

在逻辑分析仪内观察 IR 发送波形。波形如下图所示。

这里应该是 IR 发送波形的图片

IR 发送波形

代码介绍

该章节主要介绍示例中的初始化和相应功能实现的代码和流程说明。

源码路径

工程文件和源码路径如下:

  • 工程路径: sdk\samples\peripheral\ir\tx\proj

  • 源码路径: sdk\samples\peripheral\ir\tx\src

初始化

外设的初始化流程可参考 General Introduction 中的 初始化流程 部分。

  1. 调用 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);
    }
    
  2. 调用 RCC_PeriphClockCmd() ,开启 IR 时钟。

  3. 对 IR 外设进行初始化:

    1. 定义 IR_InitTypeDef 类型 IR_InitStruct ,调用 IR_StructInit()IR_InitStruct 预填默认值。

    2. 根据需求修改 IR_InitStruct 参数,IR 的初始化参数配置如下表。

    3. 调用 IR_Init(),初始化 IR 外设。

IR 初始化参数

IR Hardware Parameters

Setting in the IR_InitStruct

IR

Sample Clock

IR_InitTypeDef::IR_Freq

38000

IR Duty Cycle

IR_InitTypeDef::IR_DutyCycle

2

IR Mode

IR_InitTypeDef::IR_Mode

IR_MODE_TX

IR Tx Threshold

IR_InitTypeDef::IR_TxFIFOThrLevel

IR_TX_FIFO_THR_LEVEL

  1. 调用 IR_INTConfig() ,配置 IR 发送 FIFO 达到阈值中断 IR_INT_TF_LEVEL 。配置 NVIC,详情参考参考 中断配置

功能实现

IR 通过中断发送数据的流程如图所示:

这里应该是 IR tx interrupt flow

IR 发送数据流程图

  1. 定义 IR 发送数据数组:有载波数据用载波个数与 0x80000000 进行或运算表示,无载波数据用载波个数与 0x00000000 进行或运算表示。

  2. 调用 IR_SendBuf() 函数,开始将发送数据加载到 IR TX FIFO 中。

  3. 记录已经发送的数据个数 IR_TX_Count

  4. 调用 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);
  1. 使能 IR 外设后,IR 开始发送数据。当 IR 发送 FIFO 数据个数小于设置的发送阈值(此例中设为 2)时,触发 IR_INT_TF_LEVEL 中断,进入中断处理函数。

    1. 屏蔽 IR_INT_TF_LEVEL 中断。

    2. 分批发送 IR 数据。

      1. 如果剩余待发送的数据个数大于发送 FIFO 的容量,说明仍有大量数据未发送。此时,需要向 IR 发送 FIFO 中加载 IR_TX_FIFO_SIZE - IR_TX_FIFO_THR_LEVEL 个数据并发送。

      2. 如果剩余待发送的数据个数大于 0 但小于发送 FIFO 的容量,表示剩余的数据不多,当前可以将这些数据全部发送。这时,需要将剩余的数据全部加载到 IR 发送 FIFO 中。

      3. 否则,如果没有剩余数据,说明数据已全部发送完毕,失能 IR_INT_TF_LEVEL 中断。

    3. 清除 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);
    }