主题中讨论的其他器件: 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