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.

[参考译文] TMS320F28020:SCI 时钟混淆

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1117357/tms320f28020-sci-clock-confusion

器件型号:TMS320F28020
主题中讨论的其他器件: C2000WARE

大家好、

我现在再回答有关设置 SCI 波特率的更多问题。

在上一集中、由于 SYSCLK 以50MHz 运行、我获得了不合理的波特率、但我认为它是40MHz。  纠正错误有助于纠正问题、但似乎仍然存在 kink。

当 SYSCLK 运行在40MHz 时(确认、再次确认、之后再次检查)、BRR 值仍然不会与输出端测量的波特率进行同步。

下面是我遵循的路径: (从 Driverlib 示例代码借用的 SCI 代码、TIREX 上的"Example_F2802xSCI_FFDLB.c")

将 SYSCLK 设置为40MHz:

在我的目标(原型组装)中使用 TMS320F28020 (规格为40MHz)。

将 PLL 设置为乘以8和除以2:

 

    //
    // Setup the PLL for x8 /2 which will yield 40Mhz = 10Mhz * 8 / 2
    //
    PLL_setup(myPll, PLL_Multiplier_8, PLL_DivideSelect_ClkIn_by_2);    // 10MHz x (8/2) = 40MHz

在 XCLKOUT 上有一个示波器、并且将预分频器设置为1分频(以匹配 SYSCLK 的40MHz):

    //
    // Setup the clock out prescaler to check SYSCLK frequency at XCLKOUT
    //
    CLK_setClkOutPreScaler(myClk, CLK_ClkOutPreScaler_SysClkOut_by_1);  // Div by 1 = SYSCLKOUT

以下是示波器图像:

到目前为止,很好……

使用通用代码函数将 LSPCLK 设置为40MHz:

这里是事物变得怪异的地方。

使用以下函数、不应使 LSPCLK 以40MHz 运行:

    //
    // Setup the LOSPCP to produce 40MHz LSPCLK
    //
    CLK_setLowSpdPreScaler(myClk, CLK_LowSpdPreScaler_SysClkOut_by_1);

但是、当对 BRR 应用值时、测量波特率与计算结果显示的值不匹配。  您可能需要有关我是如何实现这一点的更多详细信息、但现在让我们重点介绍上述功能。

由于上述函数、应应用于 LOSPCP 的值为零:

//! \brief Enumeration to define the low speed clock prescaler, which sets the clock frequency
//!
typedef enum
{
    CLK_LowSpdPreScaler_SysClkOut_by_1=(0 << 0),  //!< Denotes Low Speed Clock = SYSCLKOUT/1
    CLK_LowSpdPreScaler_SysClkOut_by_2=(1 << 0),  //!< Denotes Low Speed Clock = SYSCLKOUT/2
    CLK_LowSpdPreScaler_SysClkOut_by_4=(2 << 0),  //!< Denotes Low Speed Clock = SYSCLKOUT/4
    CLK_LowSpdPreScaler_SysClkOut_by_6=(3 << 0),  //!< Denotes Low Speed Clock = SYSCLKOUT/6
    CLK_LowSpdPreScaler_SysClkOut_by_8=(4 << 0),  //!< Denotes Low Speed Clock = SYSCLKOUT/8
    CLK_LowSpdPreScaler_SysClkOut_by_10=(5 << 0), //!< Denotes Low Speed Clock = SYSCLKOUT/10
    CLK_LowSpdPreScaler_SysClkOut_by_12=(6 << 0), //!< Denotes Low Speed Clock = SYSCLKOUT/12
    CLK_LowSpdPreScaler_SysClkOut_by_14=(7 << 0)  //!< Denotes Low Speed Clock = SYSCLKOUT/14
} CLK_LowSpdPreScaler_e;

但是、它是0x0002:

找到该函数的源代码、该源代码位于 TI 安装目录的以下路径中:

C:\ti\c2000Ware_4_01_00_00\device_support\f2802x\common\source\clk.c

//
// CLK_setLowSpdPreScaler -
//
void
CLK_setLowSpdPreScaler(CLK_Handle clkHandle, 
                       const CLK_LowSpdPreScaler_e preScaler)
{
    CLK_Obj *clk = (CLK_Obj *)clkHandle;

    ENABLE_PROTECTED_REGISTER_WRITE_MODE;

    //
    // set the bits
    //
    clk->LOSPCP |= preScaler;

    DISABLE_PROTECTED_REGISTER_WRITE_MODE;

    return;
}

该函数对作为函数第二个参数传入的预分频器值进行"或"运算。  由于默认复位值为0x0002、因此该函数绝不能将 LOSPCP 设置为零或任何其他不包含位1为高电平的值。  不应使用"OR-equals (或-等于)"语句:

    //
    // set the bits
    //
    clk->LOSPCP |= preScaler;

更改为"等于":

    //
    // set the bits
    //
    clk->LOSPCP = preScaler;

或至少"和-等于":

    //
    // set the bits
    //
    clk->LOSPCP &= preScaler;

问题1:

这个函数是否正确、我对正在发生的情况有误解?

正在继续...

如果我从以下位置更改调用函数的代码行:

    //
    // Setup the LOSPCP to produce 40MHz LSPCLK
    //
    CLK_setLowSpdPreScaler(myClk, CLK_LowSpdPreScaler_SysClkOut_by_1);

为此:

    //
    // Setup the LOSPCP to produce 40MHz LSPCLK
    //
    EALLOW;
    myClk->LOSPCP = CLK_LowSpdPreScaler_SysClkOut_by_1;
    EDIS;

然后 LOSPCP 确实会达到值0、这应将 LSPCLK 设置为以40MHz 的频率运行。

在这种配置下、BRR 的计算工作正常。

请帮助我理解。

谢谢、
Robin

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

    尊敬的 Robin:

    [引用 userid="215497" URL"~/support/microrims/C2000-microset-group/C2000/f/C2000-microset-forum/1117357/tms320f28020-sci-clock-conf困惑"]此函数是否正确,我对正在发生的情况有误解?

    感谢您的识别。 我将要求我们的软件团队进行您指出的修改。  

    此致、

    Marlyn