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.

[参考译文] TMS320F280039C:SCI (UART) TX (高波特率不连续)

Guru**** 2484615 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1431648/tms320f280039c-sci-uart-tx-at-high-baudrate-not-continuous

器件型号:TMS320F280039C
Thread 中讨论的其他器件:C2000WARE

工具与软件:

我已将 SYSCLK 配置为100MHz、并将 SCI 波特率配置为4,166,667。 我已经启用了 SCI TX FIFO、并在 ISR 中一次将2个字节加载到 FIFO 中。 无论我使用的 FIFO 级别是0、1还是2、都是如此。 传输不连续、并且2个字节之间始终存在一些死区时间。 如下图所示。

我目标的回复是持续的、对于 C2000来说、似乎没有问题。 此外、一旦将波特率减半、传输就变得连续了。

您有什么有关查看以及如何解决此问题的建议吗、尤其是因为 SCI 不支持 DMA?

BTW 我使用的是 C2000Ware 5.2.0。

 

void mySCI0_init(){
	SCI_clearInterruptStatus(mySCI0_BASE, SCI_INT_RXFF | SCI_INT_TXFF | SCI_INT_FE | SCI_INT_OE | SCI_INT_PE | SCI_INT_RXERR | SCI_INT_RXRDY_BRKDT | SCI_INT_TXRDY);
	SCI_clearOverflowStatus(mySCI0_BASE);
	SCI_resetTxFIFO(mySCI0_BASE);
	SCI_resetRxFIFO(mySCI0_BASE);
	SCI_resetChannels(mySCI0_BASE);
	SCI_setConfig(mySCI0_BASE, DEVICE_LSPCLK_FREQ, 4125000, (SCI_CONFIG_WLEN_8|SCI_CONFIG_STOP_ONE|SCI_CONFIG_PAR_NONE));
	SCI_disableLoopback(mySCI0_BASE);
	SCI_performSoftwareReset(mySCI0_BASE);
	SCI_enableInterrupt(mySCI0_BASE, SCI_INT_RXFF | SCI_INT_TXFF);
	SCI_setFIFOInterruptLevel(mySCI0_BASE, SCI_FIFO_TX0, SCI_FIFO_RX2);
	SCI_enableFIFO(mySCI0_BASE);
	SCI_enableModule(mySCI0_BASE);
}

//
// SCI0 TX ISR
//
 __interrupt void INT_mySCI0_TX_ISR(void)
{
    uint16_t char_tx[2];

    if(xmtCount < xmtXferSize) {
        char_tx[0] = (ledXmtBuffer[BUS1][xmtCount] & 0xFF00) >> 8;
        char_tx[1] = (ledXmtBuffer[BUS1][xmtCount] & 0x00FF);
        SCI_writeCharArray(mySCI0_BASE, char_tx, 2);
        xmtCount++;
    }
    else {
        // Signal to application the transfer is done
        xmtDone[BUS1] = 1;
        Interrupt_disable(INT_mySCI0_TX);
    }

    //
    // Acknowledge this interrupt to receive more interrupts
    //
    SCI_clearInterruptStatus(mySCI0_BASE, SCI_INT_TXFF);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

    return;
}

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

    尊敬的 Gus:

    我看到已为您分配了该主题。 因此、除了 SPI、您现在也是 SCI 专家如果您有任何问题、请告诉我。 如果需要、我还可以向您共享完整代码。

    BR、

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

    尊敬的 Ben:

    对存储器有一些访问时间、也会对 SCI 存储器映射寄存器进行写入。 我相信这些读取和写入周期最终会限制 SCI 的有效吞吐量。 我正在寻找与此相关的一些基准、以便更好地了解我们可以预期的吞吐量。  

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

    尊敬的 Gus:

    感谢您的回答。 我也在想这样的东西、但我惊讶地看到提高 FIFO 中断级别并没有什么帮助。 希望您可以从基准测试中找到一些东西。 是否有任何 C2000、SCI 可在其中使用 DMA 来实现持续数据传输?

    BR、

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

    Ben、

    我对您的问题没有确切的答案、但我有一些近似值。 下面有一个应用手册、其中包含一些重要的基准测试信息。 它并不是特定于 SCI、但在 第3.1节中有一些关键点、详细描述了中断响应延迟。

    https://www.ti.com/lit/an/spracw5a/spracw5a.pdf

    • 表3-1列出了 ADC 中断的"硬件锁存和响应"和"编译器上下文保存"周期。 我认为同样适用于您的用例、因为您使用中断来加载 SCI FIFO。
    • 表3-2列出了 PWM MMR 写入周期、此周期有可能与 SCI FIFO 写入周期相似。

    根据数据、假设从 SCI 生成中断到 CPU 向 FIFO 写入两个字符、大约需要 ISR 延迟+ RAM 读取+ SCI 写入=[14 + 23]+[3*2]+[3*2]= 49个周期。 此处我假设 RAM 读取有3个周期、我忽略 ISR 中的"if"语句、AND 和 shift 的周期、任何 SCI_writeCharArray ()延迟以及后面的代码。 使用这些周期、您的吞吐量限制为100Mhz / 49 *16位~= 32M 位/秒 如果你有一个相应的 RX ISR、那么我认为我们可以预期会有一半的吞吐量、这是因为 CPU 还必须处理 RX ISR、并且在 C28x 上默认没有中断抢占。 其余被忽视的事情可以解释其余的。  

    可尝试增加吞吐量的方法如下:

    • 通过将更多数据写入 SCI TX FIFO 来降低 ISR 延迟。 FIFO 深度为16个字符、尽可能使用!
    • 尽可能优化 ISR 代码。 你可以做的一件事是避免使用 SCI_writeCharArray () drivelib API。 您可以使用 HWREGH 指令替换此值、因为您提前知道这个值1。 启用 FIFO、请按2。 要写入的字符数、3. FIFO 状态和4. 而不会使用该函数的返回值。

    //*****************************************************************************
    //
    // SCI_writeCharArray
    //
    //*****************************************************************************
    void
    SCI_writeCharArray(uint32_t base, const uint16_t * const array,
                       uint16_t length)
    {
        //
        // Check the arguments.
        //
        ASSERT(SCI_isBaseValid(base));
    
        uint16_t i;
        //
        // Check if FIFO enhancement is enabled.
        //
        if(SCI_isFIFOEnabled(base))
        {
            //
            // FIFO is enabled.
            // For loop to write (Blocking) 'length' number of characters
            //
            for(i = 0U; i < length; i++)
            {
                //
                // Wait until space is available in the transmit FIFO.
                //
                while(SCI_getTxFIFOStatus(base) == SCI_FIFO_TX15)
                {
                }
    
                //
                // Send a char.
                //
                HWREGH(base + SCI_O_TXBUF) = array[i];
            }
        }
        else
        {
            //
            // FIFO is not enabled.
            // For loop to write (Blocking) 'length' number of characters
            //
            for(i = 0U; i < length; i++)
            {
                //
                // Wait until space is available in the transmit buffer.
                //
                while(!SCI_isSpaceAvailableNonFIFO(base))
                {
                }
    
                //
                // Send a char.
                //
                HWREGH(base + SCI_O_TXBUF) = array[i];
            }
        }
    }

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

    尊敬的 Gus:

    很抱歉这么晚才回复。 我终于有时间处理这件事。 根据您的建议、尽可能使用 TX FIFO、并使用 HWREGH 指令优化 TX 和 RX ISR、我现在得到了一个持续传输。 请注意、下图中所用的是 CAN 收发器。 因此、RX 会在 TX 线上回送。

    非常感谢您的建议!!

    BR