IR GDMA Receive

该示例演示如何利用 GDMA 接收 IR 数据。

使用 P2_6 引脚作为 PWM 输出引脚,输出 PWM 波形用于模拟发送端数据。 将 PWM 输出引脚连接到 IR 输入引脚。

IR 通过 GDMA 接收数据,接收达到指定数量后会触发 GDMA 中断。

环境需求

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

硬件连线

连接 PWM 输出引脚 P2_6 和 IR 接收引脚 P2_5。

配置选项

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

    #define IR_RX_PIN               P2_5
    #define PWM_OUT_PIN             P2_6
    
  2. 可配置如下宏修改 PWM 配置信息。

    #define PWM_HIGH_COUNT                          (20000 - 1)
    #define PWM_LOW_COUNT                           (20000 - 1)
    

编译和下载

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

测试验证

  1. 初始化完毕后,PWM 开始输出波形。其中高电平与低电平的时间分别为 PWM_HIGH_COUNTPWM_LOW_COUNT 的 40MHz 周期数,与 IR 设置的采样频率 40MHz 相同。

  2. IR 接收到数据,GDMA 将 IR 数据搬运至内存。当 GDMA 搬运 IR 的数据完成时,触发 GDMA 中断。在 GDMA 中断函数内打印搬运的数据长度和内容。

    io_handle_gdma_msg: IR_GDMA_Rev_Data_Len = 80
    io_handle_gdma_msg: GDMA_Recv_Buf[0] = 0x00004e1e
    io_handle_gdma_msg: GDMA_Recv_Buf[1] = 0x80004e1f
    io_handle_gdma_msg: GDMA_Recv_Buf[2] = 0x00004e1f
    io_handle_gdma_msg: GDMA_Recv_Buf[3] = 0x80004e1f
    ...
    io_handle_gdma_msg: GDMA_Recv_Buf[78] = 0x00004e1f
    io_handle_gdma_msg: GDMA_Recv_Buf[79] = 0x80004e1f
    ...
    

备注

0x00004e1f 代表 IR 接收低电平的周期数,与 PWM_LOW_COUNT 值对应。0x80004e1f 代表 IR 接收高电平的周期数,其中 0x4e1f 与 PWM 的 PWM_HIGH_COUNT 值对应,0x80000000 代表高电平。

代码介绍

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

源码路径

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

  • 工程路径: sdk\samples\peripheral\ir\rx+gdma\proj

  • 源码路径: sdk\samples\peripheral\ir\rx+gdma\src

初始化

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

  1. 调用 Pad_Config()Pinmux_Config(),配置对应引脚的 PAD 和 PINMUX。

    void board_ir_init(void)
    {
        Pad_Config(IR_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
        Pad_PullConfigValue(IR_RX_PIN, PAD_PULL_STRONG);
    
        Pinmux_Config(IR_RX_PIN, IRDA_RX);
    }
    
    void board_pwm_init(void)
    {
        Pad_Config(PWM_OUT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH);
        /* Normal mode */
        Pinmux_Config(PWM_OUT_PIN, PWM_OUT_PINMUX);
    }
    
  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

40000000

IR Mode

IR_InitTypeDef::IR_Mode

IR_MODE_RX

IR Rx Mode

IR_InitTypeDef::IR_RxStartMode

IR_RX_AUTO_MODE

IR Rx Trigger Mode

IR_InitTypeDef::IR_RxTriggerMode

IR_RX_FALL_EDGE

IR Rx GDMA Enable

IR_InitTypeDef::IR_RxDmaEn

ENABLE

IR Rx Waterlevel

IR_InitTypeDef::IR_RxWaterLevel

4

  1. 调用 IR_Cmd() ,使能 IR 外设。

  2. 调用 RCC_PeriphClockCmd() ,开启 TIM 时钟。

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

    1. 定义 TIM_TimeBaseInitTypeDef 类型 TIM_InitStruct ,调用 TIM_StructInit()TIM_InitStruct 预填默认值。

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

    3. 调用 TIM_TimeBaseInit(),初始化 TIM 外设。

    4. 调用 TIM_Cmd(),使能 TIM 外设。

TIM 初始化参数

TIM Hardware Parameters

Setting in the TIM_InitStruct

TIM

TIM Mode

TIM_TimeBaseInitTypeDef::TIM_Mode

TIM_Mode_UserDefine

PWM Enable

TIM_TimeBaseInitTypeDef::TIM_PWM_En

ENABLE

PWM High Count

TIM_TimeBaseInitTypeDef::TIM_PWM_High_Count

PWM_HIGH_COUNT

PWM Low Count

TIM_TimeBaseInitTypeDef::TIM_PWM_Low_Count

PWM_LOW_COUNT

  1. 调用 RCC_PeriphClockCmd() ,开启 GDMA 时钟。

  2. 对 GDMA 外设进行初始化:

    1. 定义 GDMA_InitTypeDef 类型 GDMA_InitStruct ,调用 GDMA_StructInit()GDMA_InitStruct 预填默认值。

    2. 根据需求修改 GDMA_InitStruct 参数。GDMA 通道的初始化参数配置如下表。调用 GDMA_Init(),初始化 GDMA 外设。

    3. 配置 GDMA 总传输完成中断 GDMA_INT_Transfer 和 NVIC。NVIC 相关配置可参考 中断配置

    4. 调用 GDMA_Cmd() 使能对应 GDMA 通道传输。

GDMA 初始化参数

GDMA Hardware Parameters

Setting in the GDMA_InitStruct

GDMA Channel

Channel Num

GDMA_InitTypeDef::GDMA_ChannelNum

1

Transfer Direction

GDMA_InitTypeDef::GDMA_DIR

GDMA_DIR_PeripheralToMemory

Buffer Size

GDMA_InitTypeDef::GDMA_BufferSize

80

Source Address Increment or Decrement

GDMA_InitTypeDef::GDMA_SourceInc

DMA_SourceInc_Fix

Destination Address Increment or Decrement

GDMA_InitTypeDef::GDMA_DestinationInc

DMA_DestinationInc_Inc

Source Data Size

GDMA_InitTypeDef::GDMA_SourceDataSize

GDMA_DataSize_Word

Destination Data Size

GDMA_InitTypeDef::GDMA_DestinationDataSize

GDMA_DataSize_Word

Source Burst Transaction Length

GDMA_InitTypeDef::GDMA_SourceMsize

GDMA_Msize_4

Destination Burst Transaction Length

GDMA_InitTypeDef::GDMA_DestinationMsize

GDMA_Msize_4

Source Address

GDMA_InitTypeDef::GDMA_SourceAddr

(&IR->IR_RX_FIFO)

Destination Address

GDMA_InitTypeDef::GDMA_DestinationAddr

GDMA_Recv_Buf

Source Handshake

GDMA_InitTypeDef::GDMA_SourceHandshake

GDMA_Handshake_IR_RX

功能实现

  1. 使能 TIM 外设后,TIM 开始输出 PWM 波形。IR 接收到数据后,将数据从 (&IR->IR_RX_FIFO) 搬运至 GDMA_Recv_Buf

  2. 当 GDMA 搬运数据完成时,触发 GDMA_INT_Transfer 中断,在中断函数内打印收到的数据,并重新使能 GDMA 以继续搬运。

    void IO_TEST_GDMA_Channel_Handler(void)
    {
        GDMA_INTConfig(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer, DISABLE);
        GDMA_Cmd(IO_TEST_GDMA_CHANNEL_MUM, DISABLE);
        IR_GDMA_Rev_Data_Len = IO_TEST_GDMA_TRANSFER_SIZE;
        io_handle_gdma_msg();
        GDMA_ClearINTPendingBit(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer);
        GDMA_Cmd(IO_TEST_GDMA_CHANNEL_MUM, ENABLE);
        GDMA_INTConfig(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer, ENABLE);
    }
    
    void io_handle_gdma_msg(void)
    {
        DBG_DIRECT("io_handle_gdma_msg: IR_GDMA_Rev_Data_Len = %d \r\n", IR_GDMA_Rev_Data_Len);
        for (uint32_t i = 0; i < IR_GDMA_Rev_Data_Len; i++)
        {
            DBG_DIRECT("io_handle_gdma_msg: GDMA_Recv_Buf[%d] = 0x%x \r\n", i, GDMA_Recv_Buf[i]);
        }
    }
    

See Also

相关 API Reference 请查看: