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.

[参考译文] TMS320F28376S:时钟配置问题:波特率恰好是应有波特率的一半!

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1410210/tms320f28376s-clock-configuration-issues-baud-rate-is-exactly-half-of-what-it-should-be

器件型号:TMS320F28376S

工具与软件:

您好!  

我们遵循 driverlib 文件夹中的示例、在 SCIC 引脚上设置一个 UART 接收器、以在5MBaud 下运行。  

接收到负载组帧错误后、我们在 TX 引脚上设置相同的配置、并使用逻辑分析仪、此分析仪显示实际波特率为2.5兆波特。  

// initSCIAFIFO - Configure SCIC FIFO
void initSCICFIFO()
{
    // Baud rate setting
    SCI_setBaud(SCIC_BASE, 200000000, 5000000);
    SCI_setBaud(SCIA_BASE, 200000000, 5000000);

    // 8 char bits, 1 stop bit, even parity. Baud, SYSCLK, LSPCLK defines...
    SCI_setConfig(SCIC_BASE, 200000000, 5000000, (SCI_CONFIG_WLEN_8 |
                                                        SCI_CONFIG_STOP_ONE |
                                                        SCI_CONFIG_PAR_EVEN));
    SCI_setConfig(SCIA_BASE, 200000000, 5000000, (SCI_CONFIG_WLEN_8 |
                                                        SCI_CONFIG_STOP_ONE |
                                                        SCI_CONFIG_PAR_EVEN));

    SCI_enableModule(SCIC_BASE);
    SCI_disableLoopback(SCIC_BASE);
    SCI_resetChannels(SCIC_BASE);
    SCI_enableFIFO(SCIC_BASE);

    SCI_enableModule(SCIA_BASE);
    SCI_disableLoopback(SCIA_BASE);
    SCI_resetChannels(SCIA_BASE);
    SCI_enableFIFO(SCIA_BASE);

    // RX and TX FIFO Interrupts disabled initially
    SCI_disableInterrupt(SCIC_BASE, SCI_INT_RXFF);
    SCI_disableInterrupt(SCIC_BASE, SCI_INT_RXERR);
    SCI_disableInterrupt(SCIC_BASE, SCI_INT_RXRDY_BRKDT);
    SCI_disableInterrupt(SCIC_BASE, SCI_INT_TXFF);

    SCI_disableInterrupt(SCIA_BASE, SCI_INT_RXFF);
    SCI_disableInterrupt(SCIA_BASE, SCI_INT_RXERR);
    SCI_disableInterrupt(SCIA_BASE, SCI_INT_RXRDY_BRKDT);
    SCI_disableInterrupt(SCIA_BASE, SCI_INT_TXFF);

    // Generate interrupt on receipt of three characters (8-bits each, 12-bits curr/volts).
    SCI_setFIFOInterruptLevel(SCIC_BASE, SCI_FIFO_TX3, SCI_FIFO_RX3);
    SCI_performSoftwareReset(SCIC_BASE);
    SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX1, SCI_FIFO_RX3);
    SCI_performSoftwareReset(SCIA_BASE);

    SCI_resetTxFIFO(SCIC_BASE);
    SCI_resetRxFIFO(SCIC_BASE);
    SCI_resetTxFIFO(SCIA_BASE);
    SCI_resetRxFIFO(SCIA_BASE);

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

此后、我们假设时钟出现了问题-无论我们将波特率设置为什么、它始终是该值的一半。  

我们为 SYSCLK 和 LSPCLK 都调用了 getClock 函数、这两个函数都返回200MHz。 滚动查看 SYSCTL 的 API 指南后、我唯一能想到的更改是 PLL 时钟分频器。 在器件初始设置后、我们插入了以下代码、如下所示:

// Initialize device clock and peripherals
    Device_init();


    SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_1);
    
    // Set PLL to max frequency, argument zero = DIV by 1.
    SysCtl_setPLLSysClk(0);

    lowClockFreq = SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ);
    sysClockFreq = SysCtl_getClock(DEVICE_OSCSRC_FREQ);
    properClockFreq = SysCtl_getClock(SYSCTL_DEFAULT_OSC);

我们重新运行测试发现、波特率现在为5兆波特、并且我们不再遇到组帧错误。

我们在软件中使用 DAC 来直观显示转换后接收到的 UART 数据、但 DACA 和 DACB 都始终保持在3.3V。  

getClock 函数现在返回两倍于常规值、例如、读取200MHz 时读取的是400MHz。  

这里发生了什么? 尽管函数调用显示我的波特率都是200MHz、但为什么我的波特率为2.5MBaud 时它应该是5Mbaud?

是否会意外地将时钟设置为400MHz、这会导致时钟在该频率下运行、而这是否会损坏器件、从而导致 DAC 始终保持3.3V 的电压?

寄存器中"BRR"的值为"4"它与 SYSCLK 和 LSPCLK 对齐、二者均为200MHz (波特率为5MBaud)。


有人能解释一下这里发生了什么吗? SCI 时钟似乎甚至不是从 PLLSYSCLK 派生的、并且显示 LSPCLK 的200MHz 和 SYSCLK 的函数调用使我想知道这个额外的2除法可能来自哪里、以及我是否修复了这个问题。  

此致、

JmH

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

    器件型号:TMS320F28376S

    工具与软件:

    您好!  

    我们遵循 driverlib 文件夹中的示例、在 SCIC 引脚上设置一个 UART 接收器、以在5MBaud 下运行。  

    接收到负载组帧错误后、我们在 TX 引脚上设置相同的配置、并使用逻辑分析仪、此分析仪显示实际波特率为2.5兆波特。  

    // initSCIAFIFO - Configure SCIC FIFO
    void initSCICFIFO()
    {
        // Baud rate setting
        SCI_setBaud(SCIC_BASE, 200000000, 5000000);
        SCI_setBaud(SCIA_BASE, 200000000, 5000000);
    
        // 8 char bits, 1 stop bit, even parity. Baud, SYSCLK, LSPCLK defines...
        SCI_setConfig(SCIC_BASE, 200000000, 5000000, (SCI_CONFIG_WLEN_8 |
                                                            SCI_CONFIG_STOP_ONE |
                                                            SCI_CONFIG_PAR_EVEN));
        SCI_setConfig(SCIA_BASE, 200000000, 5000000, (SCI_CONFIG_WLEN_8 |
                                                            SCI_CONFIG_STOP_ONE |
                                                            SCI_CONFIG_PAR_EVEN));
    
        SCI_enableModule(SCIC_BASE);
        SCI_disableLoopback(SCIC_BASE);
        SCI_resetChannels(SCIC_BASE);
        SCI_enableFIFO(SCIC_BASE);
    
        SCI_enableModule(SCIA_BASE);
        SCI_disableLoopback(SCIA_BASE);
        SCI_resetChannels(SCIA_BASE);
        SCI_enableFIFO(SCIA_BASE);
    
        // RX and TX FIFO Interrupts disabled initially
        SCI_disableInterrupt(SCIC_BASE, SCI_INT_RXFF);
        SCI_disableInterrupt(SCIC_BASE, SCI_INT_RXERR);
        SCI_disableInterrupt(SCIC_BASE, SCI_INT_RXRDY_BRKDT);
        SCI_disableInterrupt(SCIC_BASE, SCI_INT_TXFF);
    
        SCI_disableInterrupt(SCIA_BASE, SCI_INT_RXFF);
        SCI_disableInterrupt(SCIA_BASE, SCI_INT_RXERR);
        SCI_disableInterrupt(SCIA_BASE, SCI_INT_RXRDY_BRKDT);
        SCI_disableInterrupt(SCIA_BASE, SCI_INT_TXFF);
    
        // Generate interrupt on receipt of three characters (8-bits each, 12-bits curr/volts).
        SCI_setFIFOInterruptLevel(SCIC_BASE, SCI_FIFO_TX3, SCI_FIFO_RX3);
        SCI_performSoftwareReset(SCIC_BASE);
        SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX1, SCI_FIFO_RX3);
        SCI_performSoftwareReset(SCIA_BASE);
    
        SCI_resetTxFIFO(SCIC_BASE);
        SCI_resetRxFIFO(SCIC_BASE);
        SCI_resetTxFIFO(SCIA_BASE);
        SCI_resetRxFIFO(SCIA_BASE);
    
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

    此后、我们假设时钟出现了问题-无论我们将波特率设置为什么、它始终是该值的一半。  

    我们为 SYSCLK 和 LSPCLK 都调用了 getClock 函数、这两个函数都返回200MHz。 滚动查看 SYSCTL 的 API 指南后、我唯一能想到的更改是 PLL 时钟分频器。 在器件初始设置后、我们插入了以下代码、如下所示:

    // Initialize device clock and peripherals
        Device_init();
    
    
        SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_1);
        
        // Set PLL to max frequency, argument zero = DIV by 1.
        SysCtl_setPLLSysClk(0);
    
        lowClockFreq = SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ);
        sysClockFreq = SysCtl_getClock(DEVICE_OSCSRC_FREQ);
        properClockFreq = SysCtl_getClock(SYSCTL_DEFAULT_OSC);

    我们重新运行测试发现、波特率现在为5兆波特、并且我们不再遇到组帧错误。

    我们在软件中使用 DAC 来直观显示转换后接收到的 UART 数据、但 DACA 和 DACB 都始终保持在3.3V。  

    getClock 函数现在返回两倍于常规值、例如、读取200MHz 时读取的是400MHz。  

    这里发生了什么? 尽管函数调用显示我的波特率都是200MHz、但为什么我的波特率为2.5MBaud 时它应该是5Mbaud?

    是否会意外地将时钟设置为400MHz、这会导致时钟在该频率下运行、而这是否会损坏器件、从而导致 DAC 始终保持3.3V 的电压?

    寄存器中"BRR"的值为"4"它与 SYSCLK 和 LSPCLK 对齐、二者均为200MHz (波特率为5MBaud)。

    有人能解释一下这里发生了什么吗? SCI 时钟似乎甚至不是从 PLLSYSCLK 派生的、并且显示 LSPCLK 的200MHz 和 SYSCLK 的函数调用使我想知道这个额外的2除法可能来自哪里、以及我是否修复了这个问题。  

    此致、

    JmH

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

    尊敬的 JM:

    我看到您已经发布了相同的问题、因此我将关闭该主题、并 请 专家查看另一个主题。

    此致、

    Aishwarya.