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.

PLL只能倍频,不能分频,请工程师指点。谢谢。



这是我的整个程序!

void PLL_init(unsigned int main_PLLM, unsigned int main_PLLD)
{
CSL_PllcHandle hPllc;
Uint8 goStatus;
hPllc=CSL_PLLC_open (0);

CSL_BootCfgUnlockKicker(); //并不锁定Kicker以便配置boot方便写入MMR寄存器的值

CSL_PLLC_setPllCtrlPllEnSrc (hPllc, 0); // Enable PLLEN bit configuration
CSL_PLLC_setPllCtrlPllEn (hPllc, 0); // Put PLLC in Bypass mode
CSL_PLLC_setPllCtrlPllPowerDown(hPllc,0); // PUT PLLPWRDN = 0
CSL_PLLC_setPllCtrlPllReset (hPllc, 1); // Put PLLC in reset

CSL_PLLC_setPllMultiplierCtrlReg (hPllc, main_PLLM); // Setup x1 multiplier rate PLLM=0

CSL_PLLC_setPllSecCtrlReg (hPllc, 0x11); //设置PLL第二功能寄存器,分频系数为1分频

CSL_PLLC_setPllDivReg (hPllc,17,1,0x01); // Setup /1 divider rate and enable divider 1

CSL_PLLC_setPllAlignCtrlReg (hPllc, 1); // Set the respective ALNn bit in ALNCTL register

CSL_PLLC_setPllCtrlPllReset (hPllc, 0); // Bring PLLC out of reset
CSL_PLLC_setPllCtrlPllEn (hPllc, 1); // Put PLLC back in PLL mode

CSL_PLLC_setPllCmdReg (hPllc, 1); // Start GO operation
CSL_PLLC_getPllStatusReg (hPllc, &goStatus);// Ensure no GO operation in progress already

while (goStatus != 0)
{
CSL_PLLC_getPllStatusReg (hPllc, &goStatus);// wait some time and recheck GOSTAT status
}
CSL_BootCfgLockKicker(); //锁定Kicker保护boot MMR寄存器不被修改
}

倍频,分频修改的函数

CSL_PLLC_setPllMultiplierCtrlReg (hPllc, main_PLLM); // Setup x1 multiplier rate PLLM=0

CSL_PLLC_setPllSecCtrlReg (hPllc, 0x11); //设置PLL第二功能寄存器,分频系数为1分频

CSL_PLLC_setPllDivReg (hPllc,17,1,0x01); // Setup /1 divider rate and enable divider 1

我才用的是TI的6678的测试版TMXEVM6678LE,测试点T12,为DSP内核系统时钟输出。

我秀该倍频因子,PLLM是,能够产生倍频,不仅大概16MHZ左右,比如

PLLM=0    输出16.6MHZ,

PLLM=1    输出33.3MHZ,

PLLM=2    输出50.0MHZ,

PLLM=3    输出66.8MHZ,

PLLM=4    输出83.3MHZ,

PLLM=5    输出100MHZ,

PLLM=6    输出116MHZ,

但是我设置分频因子时候,却是无效的,请工程师给我看看,分析分析我的错误。另外我不明白两个分频因子是如何计算左后的系统时钟的。请工程师给我讲解下,谢谢了。

  • 请参考以下代码

     

    /*DSP core PLL configuration*/
    void KeyStone_main_PLL_init ( unsigned int main_PLLM, unsigned int main_PLLD)
    {
     unsigned int i;

     if(0<main_PLLM&&main_PLLM<=4096&&0<main_PLLD&&main_PLLD<=64)
     {
      CSL_BootCfgUnlockKicker();

      boot_cfg_regs->MAIN_PLL_CTL1 |= 0x00000040; //Set ENSAT = 1

      printf("Initialize main PLL = x%d/%d\n", main_PLLM, main_PLLD);

      /*1. If executing this sequence immediately after device power-up, you must allow for*/
      /*the PLL to become stable. PLL stabilization time is 100 μs.                       */
      for(i=0; i< 20000; i++)
       asm(" nop 5");

      /*2. Check the status of BYPASS bit in SECCTL register, execute following steps if   */
      /*BYPASS == 1 (if bypass enabled), otherwise skip this step:                         */
      if(0 != (pllc_regs->SECCTL & 0x00800000))
      {  
       /*a. In MAINPLLCTL1, write ENSAT = 1 (for optimal PLL operation)                     */
       boot_cfg_regs->MAIN_PLL_CTL1 |= 0x00000040;      /*Set ENSAT bit = 1*/

       /*b. In PLLCTL, write PLLENSRC = 0 (enable PLLEN to control PLL controller mux       */
       pllc_regs->PLLCTL &= (~(1<<5));

       /*c. In PLLCTL, write PLLEN = 0 (bypass enabled in PLL controller mux)               */
       pllc_regs->PLLCTL &= (~(1<<0));

       /*d. Wait 4 cycles of the reference clock CLKIN (to make sure the PLL controller     */
       /*mux switches properly to the bypass)                                               */
       for(i=0; i< 4*8192/5+1; i++)
        asm(" nop 4");

       /*e. In SECCTL, write BYPASS = 1 (bypass enabled in PLL mux)                         */
       pllc_regs->SECCTL |= 0x00800000;

       /*f. In PLLCTL, write PLLPWRDN = 1 (power down the PLL)                              */
       pllc_regs->PLLCTL |= (1<<1); //Power down the PLL

       /*g. Wait for at least 5 μs based on the reference clock CLKIN (PLL power down      */
       /*toggling time)                                                                     */
       for(i=0; i< 1000; i++)
        asm(" nop 5");

       /*h. In PLLCTL, write PLLPWRDN = 0 (power up the PLL)                                */
       pllc_regs->PLLCTL &= ~(1<<1);         // Power up PLL
      }

      /*3. In PLLCTL, write PLLRST = 1 (PLL is reset)                                      */
      pllc_regs->PLLCTL |= (1<<3);

      /*4. PLLM is split in two different registers. Program PLLM[5:0] in PLL multiplier   */
      /*control register (PLLM) and PLLM[12:6] in MAINPLLCTL0 register                     */
      /*5. BWADJ is split in two different registers. Program BWADJ[7:0] in                */
      /*MAINPLLCTL0 and BWADJ[11:8] in MAINPLLCTL1 register. BWADJ value                   */
      /*must be set to ((PLLM + 1) >> 1) - 1)                                              */
      /*6. Program PLLD in MAINPLLCTL0 register                                            */
      boot_cfg_regs->MAIN_PLL_CTL0 = ((main_PLLM-1)<<24)|  /*BWADJ[7:0]*/
       (((main_PLLM*2-1)&0x1FC0)<<6)|(main_PLLD-1);
      pllc_regs->PLLM= (main_PLLM*2-1)&0x3F;
      boot_cfg_regs->MAIN_PLL_CTL1 &= 0xFFFFFFF0;
      boot_cfg_regs->MAIN_PLL_CTL1 |= (main_PLLM-1)>>8; /*BWADJ[11:8]*/

      /*7. In SECCTL, write OD (Output Divide) = 1 (that is divide-by-2)                   */
      pllc_regs->SECCTL &= 0xff87ffff;
      pllc_regs->SECCTL |= 0x00080000;
      
      /*8. If necessary, program PLLDIVn. Note that you must apply the GO operation to     */
      /*change these dividers to a new ratios (see Section 3.2 ‘‘Divider n (D1 to Dn) and*/
      /*GO Operation ’’ on page 3-3).                                                    */

      /*9. Wait for at least 7 μs based on the reference clock CLKIN (PLL reset time)     */
      for(i=0; i< 2000; i++)
       asm(" nop 5");

      /*10. In PLLCTL, write PLLRST = 0 (PLL reset is released)                            */
      pllc_regs->PLLCTL &= (~(1<<3));

      /*11. Wait for at least 500 × CLKIN cycles × (PLLD + 1) (PLL lock time)            */
      for(i=0; i< 10000*main_PLLD; i++)
       asm(" nop 5");

      /*12. In SECCTL, write BYPASS = 0 (enable PLL mux to switch to PLL mode)             */
      pllc_regs->SECCTL &= ~(0x00800000);
      
      /*13. Set the PLLEN bit in PLLCTL to 1 to enable PLL mode*/
      pllc_regs->PLLCTL= pllc_regs->PLLCTL|(1<<0);

     }

    }

  • 你好。我参考了你的程序,但是还是不能解决问题,我直接采用的是CSL库来做的。不是直接操作寄存器。谢谢你指导。