This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS570LC4357:如何使用 DMA 进行 I2C 发送和接收?

Guru**** 2457760 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1184834/tms570lc4357-how-to-use-dma-for-i2c-transmit-and-receive

器件型号:TMS570LC4357

您是否有任何使用 DMA 进行 I2C 传输和接收的示例代码?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    使用 DMA 进行 I2C 数据传输类似于使用 DMA 进行 SPI 或 SCI 传输。  

    在主发送器模式下、在 START 条件之后会生成一个发送事件。 DMA 根据接收事件和发送事件接收数据并发送数据。 读取和写入事件的时序分别与 I2CRRDY (I2CRINT)和 I2CXRDY (I2CXINT)相同。

    我没有带 DMA 的 I2C 示例。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    uint8 TX_PACK[bsize]={'H'、'E'、'R'、'C'、'U'、'L'、'E'、'S'、'M'、'I'、'C'、'R'、'O'、'-'、'T'、'I'};
    uint8 RX_PACK[bsize]={0};

    #define I2C1_TX_ADDR ((uint32_t)(&(i2cREG1->DXR))
    #define I2C1_RX_ADDR ((uint32_t)(&(i2cREG1->DRR))
    //启用 CPU 对中断请求的响应
    _enable_IRQ ();
    /* i2c 初始化*/
    i2cInit();

    /*配置要与*/通话的从机地址
    i2cSetSlaveAdd (i2cREG1、SLV_add);
    i2cSetDirection (i2cREG1、I2C_transmitter);


    /*设置 i2c 自有地址*/
    i2cSetOwnAdd (i2cREG1、Own_add);

    /*启用内部回送*/
    i2cEnableLoopback (i2cREG1);

    dmaReqAssign (DMA_CH0、DMA_REQ10);
    dmaReqAssign (DMA_CH1、DMA_REQ11);

    dmaSetChEnable (DMA_CH0、DMA_HW);
    dmaSetChEnable (DMA_CH1、DMA_HW);

    dmaEnableInterrupt (DMA_CH0、BTC、DMA_INTA);
    dmaEnableInterrupt (DMA_CH1、BTC、DMA_INTA);

    vDmaConfigCtrlTxPacket ((uint32_t)(&TX_PACK[0])、I2C1_TX_ADDR、16);
    vDmaConfigCtrlRxPacket (I2C1_RX_ADDR、(uint32_t)(&RX_PACK[0])、16);
    /*-设置用于传输的 DMA 控制数据包*/
    dmaSetCtrlPacket (DMA_CH0、g_dmaCTRLPKT1);
    dmaSetCtrlPacket (DMA_CH1、g_dmaCTRLPKT);

    dmaEnable();

    i2cREG1->DMACR |= 0x3;

    i2cSetStop (i2cREG1);

    /*发送开始条件*/
    i2cSetStart (i2cREG1);

    我看到两个 DMA 中断通知、但 RX_Pack DMA 都为0

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请更改以下代码:

    #define I2C1_TX_ADDR ((uint32_t)(&(i2cREG1->DXR))
    #define I2C1_RX_ADDR ((uint32_t)(&(i2cREG1->DRR))

    至:

    #define I2C1_TX_ADDR ((uint32_t)(&(i2cREG1->DXR))+ 3)
    #define I2C1_RX_ADDR ((uint32_t)(&(i2cREG1->DRR))+ 3)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是可行的、谢谢。 您能解释一下为什么是3个?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    TMS570LC43x 是一款大端字节序器件。   数据的最高有效字节被放置在具有最低地址的字节上。 其余数据按顺序放置在存储器中的接下来三个字节中。  

    I2CDXR[7:0]和 I2CDRR[7:0]被放置在具有最高地址的字节上。

    存储器地址        I2CDXR        I2CDRR

    ----------------------------------------

    0x20                  -             -   

    0x21                  -             -

    0x22                  DXR[15:8]       DRR[15:8]

    0x23                  DXR[7:0]        DRR[7:0]