基于xs128单片机的PLL设置

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

PLL锁相环的设置比较简单的,设置太高相对来说不够稳定,进行过PC机超频的应该很有体会,一般我们现在用的XS128我觉得设置在80MHz是比较合适的,相比DG128,这个频率已经蛮高的了。同时就是SYNR,REFDV只有在CLKSEL_PLLSEL=0的情况下才能写入,不过这是系统默认状态。

通过写REFDV(CRG参考分频寄存器)和SYNR(CRG合成器寄存器)进行设置PLL锁相环。锁相环从设定到最后稳定还是需要一点点时间的,所以需要加几条空指令。但是需要进行时钟矫正后才让时钟比较准,然后写上while(!CRGFLG_LOCK);

具体案例通过下面代码进行显示说明:

/************************************************************************************** 
    ------------------------------------ 
    Code Warrior 5.6 
    Target : MC9S12XS128 
    Crystal: 16.000Mhz  
    ============================================    
    本程序主要包括以下功能: 
     
    设定系统工作在xxMHZ bus clock时钟下; 
 
    *****************************************************************************************/  
      
    #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);  
      }     
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值