IR GDMA Transmit

该实例使用 IR 外设利用 GDMA 搬运进行数据发送,实现数据发送功能。

GDMA 会将预定义的 IR 数据从内存搬运至 IR TX FIFO 中,搬运完成后触发 GDMA 中断。

可以使用逻辑分析仪来观察 IR 发送的数据是否符合预期。

环境需求

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

硬件连线

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

配置选项

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

    #define IR_TX_PIN                       P2_5
    
  2. 可配置如下宏修改 GDMA 通道设置。

    #define IO_TEST_GDMA_CHANNEL_MUM        1           /*< Set this macro to select the GDMA Channel num. */
    
    // Set the folling macros to modify the GDMA Channel configurations.
    #if (IO_TEST_GDMA_CHANNEL_MUM == 0)
    #define IO_TEST_GDMA_Channel                GDMA_Channel0
    #define IO_TEST_GDMA_Channel_IRQn           GDMA0_Channel0_IRQn
    #define IO_TEST_GDMA_Channel_Handler        GDMA0_Channel0_Handler
    #elif IO_TEST_GDMA_CHANNEL_MUM == 1
    #define IO_TEST_GDMA_Channel                GDMA_Channel1
    #define IO_TEST_GDMA_Channel_IRQn           GDMA0_Channel1_IRQn
    #define IO_TEST_GDMA_Channel_Handler        GDMA0_Channel1_Handler
    #elif IO_TEST_GDMA_CHANNEL_MUM == 2
    #define IO_TEST_GDMA_Channel                GDMA_Channel2
    #define IO_TEST_GDMA_Channel_IRQn           GDMA0_Channel2_IRQn
    #define IO_TEST_GDMA_Channel_Handler        GDMA0_Channel2_Handler
    #elif IO_TEST_GDMA_CHANNEL_MUM == 3
    #define IO_TEST_GDMA_Channel                GDMA_Channel3
    #define IO_TEST_GDMA_Channel_IRQn           GDMA0_Channel3_IRQn
    #define IO_TEST_GDMA_Channel_Handler        GDMA0_Channel3_Handler
    #endif
    
  3. 可配置如下宏修改 GDMA 数据传输长度。

    #define IO_TEST_GDMA_TRANSFER_SIZE          IR_DATA_SIZE_MAX                       /*< Set this macro to modify the transfer size. */
    #define IR_DATA_SIZE_MAX                    68
    

编译和下载

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

测试验证

在逻辑分析仪内观察 IR 发送的波形。

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

IR 发送波形

代码介绍

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

源码路径

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

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

  • 源码路径: sdk\samples\peripheral\ir\tx+gdma\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

3

IR Mode

IR_InitTypeDef::IR_Mode

IR_MODE_TX

IR Tx GDMA Enable

IR_InitTypeDef::IR_TxDmaEn

ENABLE

IR Tx Waterlevel

IR_InitTypeDef::IR_TxWaterLevel

15

  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 相关配置可参考 中断配置

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_MemoryToPeripheral

Buffer Size

GDMA_InitTypeDef::GDMA_BufferSize

IO_TEST_GDMA_TRANSFER_SIZE

Source Address Increment or Decrement

GDMA_InitTypeDef::GDMA_SourceInc

DMA_SourceInc_Inc

Destination Address Increment or Decrement

GDMA_InitTypeDef::GDMA_DestinationInc

DMA_DestinationInc_Fix

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_1

Destination Burst Transaction Length

GDMA_InitTypeDef::GDMA_DestinationMsize

GDMA_Msize_1

Source Address

GDMA_InitTypeDef::GDMA_SourceAddr

GDMA_Send_Buf

Destination Address

GDMA_InitTypeDef::GDMA_DestinationAddr

(&IR->IR_TX_FIFO)

Destination Handshake

GDMA_InitTypeDef::GDMA_DestHandshake

GDMA_Handshake_IR_TX

功能实现

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

  2. 调用 GDMA_Cmd() 使能对应 GDMA 通道传输。调用 IR_Cmd() ,使能 IR 外设发送功能。GDMA 将数据从 GDMA_Send_Buf 搬运至 (&IR->IR_TX_FIFO)

    IR_Send_Data.CarrierFreq = 38000;
    IR_Send_Data.DataLen = IO_TEST_GDMA_TRANSFER_SIZE;
    IR_Send_Data.DataBuf[0] =  0x80000000 | 0x200;
    IR_Send_Data.DataBuf[1] =  0x00000000 | 0x100;
    ...
    IR_Send_Data.DataBuf[IR_Send_Data.DataLen - 1] =  0x80000000 | 0x800;
    
    /* Test data buffer */
    for (uint32_t i = 0; i < IO_TEST_GDMA_TRANSFER_SIZE; i++)
    {
        GDMA_Send_Buf[i] = IR_Send_Data.DataBuf[i];
    }
    
    ...
    IR_Cmd(IR_MODE_TX, ENABLE);
    
  3. 当 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);
        DBG_DIRECT("IO_TEST_GDMA_Channel_Handler\r\n");
        GDMA_ClearINTPendingBit(IO_TEST_GDMA_CHANNEL_MUM, GDMA_INT_Transfer);
    }
    

See Also

相关 API Reference 请查看: