飞思卡尔 PLL锁相环

2020-02-21 21:03发布

通俗点说,设置PLL锁相环就相当于超频,单片机超频的原因和PC机是一个道理。 分频的主要原因是外设需要的工作频率往往远低于CPU/MEMORY,这也和PC机南北桥的原理类似。

       相对来说,PLL锁相环的设置还是比较简单的,因为东西很死,完全可以照搬。只是大家也不要太贪,设置太高相对来说不够稳定,进行过PC机超频的应该很有体会,一般我们现在用的XS128我觉得设置在80MHz是比较合适的,相比前几届比赛用的DG128,这个频率已经蛮高的了。还有就是SYNR,REFDV只有在CLKSEL_PLLSEL=0的情况下才能写入,不过这是系统默认状态。

多半大家可能还会有以下几点疑问:

1.PLL锁相环怎么设置?

答:通过写REFDV(CRG参考分频寄存器)和SYNR(CRG合成器寄存器)进行设置



2.代码里while(!CRGFLG_LOCK);这句是干什么的?

答:时钟校正同步



3.为什么代码中会有多多少少的几句空语句?

答:锁相环从设定到最后稳定还是需要一点点时间的,所以需要加几条空指令

复制代码
    /**************************************************************************************
    ------------------------------------
    Code Warrior 5.0
    Target : MC9S12XS128
    Crystal: 16.000Mhz  
    ============================================   
    本程序主要包括以下功能:
     
    设定系统工作在xxMHZ bus clock时钟下;
     
    by:庞辉
    *****************************************************************************************/  
      
    #include <hidef.h>          /* common defines and macros */  
    #include <MC9S12XS128.h>     /* derivative information */  
    #pragma LINK_INFO DERIVATIVE "mc9s12xs128"  
      
    void SetBusCLK_16M(void)  
    {     
        CLKSEL=0X00;    // disengage PLL to system  
        PLLCTL_PLLON=1; // turn on PLL  
        SYNR=0x00 | 0x01;   // VCOFRQ[7:6];SYNDIV[5:0]  
                            // fVCO= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1)  
                            // fPLL= fVCO/(2 × POSTDIV)   
                            // fBUS= fPLL/2   
                            // VCOCLK Frequency Ranges  VCOFRQ[7:6]  
                            // 32MHz <= fVCO <= 48MHz    00  
                            // 48MHz <  fVCO <= 80MHz    01  
                            // Reserved                  10  
                            // 80MHz <  fVCO <= 120MHz   11                 
        REFDV=0x80 | 0x01;  // REFFRQ[7:6];REFDIV[5:0]  
                            // fREF=fOSC/(REFDIV + 1)  
                            // REFCLK Frequency Ranges  REFFRQ[7:6]  
                            // 1MHz <= fREF <=  2MHz       00  
                            // 2MHz <  fREF <=  6MHz       01  
                            // 6MHz <  fREF <= 12MHz       10  
                            // fREF >  12MHz               11                           
                            // pllclock=2*osc*(1+SYNR)/(1+REFDV)=32MHz;  
        POSTDIV=0x00;       // 4:0, fPLL= fVCO/(2xPOSTDIV)  
                            // If POSTDIV = $00 then fPLL is identical to fVCO (divide by one).  
        _asm(nop);          // BUS CLOCK=16M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void SetBusCLK_32M(void)  
    {     
        CLKSEL=0X00;                // disengage PLL to system  
        PLLCTL_PLLON=1;         // turn on PLL  
        SYNR =0x40 | 0x03;  // pllclock=2*osc*(1+SYNR)/(1+REFDV)=64MHz;                        
        REFDV=0x80 | 0x01;   
        POSTDIV=0x00;   
        _asm(nop);          // BUS CLOCK=32M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void SetBusCLK_40M(void)  
    {     
        CLKSEL=0X00;                //disengage PLL to system  
        PLLCTL_PLLON=1;         //turn on PLL  
        SYNR =0xc0 | 0x04;                          
        REFDV=0x80 | 0x01;   
        POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=80MHz;  
        _asm(nop);          //BUS CLOCK=40M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void SetBusCLK_48M(void)  
    {     
        CLKSEL=0X00;                //disengage PLL to system  
        PLLCTL_PLLON=1;         //turn on PLL  
        SYNR =0xc0 | 0x05;                          
        REFDV=0x80 | 0x01;   
        POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=96MHz;  
        _asm(nop);          //BUS CLOCK=48M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void SetBusCLK_64M(void)  
    {     
        CLKSEL=0X00;                //disengage PLL to system  
        PLLCTL_PLLON=1;         //turn on PLL  
        SYNR =0xc0 | 0x07;                          
        REFDV=0x80 | 0x01;   
        POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=128MHz;  
        _asm(nop);          //BUS CLOCK=64M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void SetBusCLK_80M(void)  
    {     
        CLKSEL=0X00;                //disengage PLL to system  
        PLLCTL_PLLON=1;         //turn on PLL  
        SYNR =0xc0 | 0x09;                          
        REFDV=0x80 | 0x01;   
        POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=160MHz;  
        _asm(nop);          //BUS CLOCK=80M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void SetBusCLK_88M(void)  
    {     
        CLKSEL=0X00;                //disengage PLL to system  
        PLLCTL_PLLON=1;         //turn on PLL  
        SYNR =0xc0 | 0x0a;                          
        REFDV=0x80 | 0x01;   
        POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=176MHz;  
        _asm(nop);          //BUS CLOCK=88M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void SetBusCLK_96M(void)  
    {     
        CLKSEL=0X00;                //disengage PLL to system  
        PLLCTL_PLLON=1;         //turn on PLL  
        SYNR =0xc0 | 0x0b;                          
        REFDV=0x80 | 0x01;   
        POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=192MHz;  
        _asm(nop);          //BUS CLOCK=96M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void SetBusCLK_104M(void)  
    {     
        CLKSEL=0X00;                //disengage PLL to system  
        PLLCTL_PLLON=1;         //turn on PLL  
        SYNR =0xc0 | 0x0c;                          
        REFDV=0x80 | 0x01;   
        POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=208MHz;  
        _asm(nop);          //BUS CLOCK=104M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void SetBusCLK_120M(void)  
    {     
        CLKSEL=0X00;                //disengage PLL to system  
        PLLCTL_PLLON=1;         //turn on PLL  
        SYNR =0xc0 | 0x0d;                          
        REFDV=0x80 | 0x01;   
        POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=240MHz;  
        _asm(nop);          //BUS CLOCK=120M  
        _asm(nop);  
        while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;  
        CLKSEL_PLLSEL =1;               //engage PLL to system;   
    }  
      
    void main(void)   
    {  
        
      EnableInterrupts;  
      
      for(;;)   
      {     
         _asm(nop);  
      }     
    }  
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。