锁相环

更新时间:2024-06-18 20:58:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

通俗点说,设置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.为什么代码中会有多多少少的几句空语句?

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

OSC、FOSC、OSCCLK:我认为这三者一样,是振荡器频率,即是我们外加晶振频率

SYNR 时钟合成寄存器

VCOFRQ[7:6]:不知道,跪求高人解答!!! SYNDIV[5:0]:不知道,跪求高人解答!!!

REFDV时钟分频寄存器

REFFRQ[7:6]:不知道,跪求高人解答 REFDIV[5:0]:不知道,跪求高人解答

FVCO:应该是系统频率(有错请更正)

FPLL、PLLCLK:我认为是一样的,即锁相环频率

FBUS、Bus Clock:我认为是一样的,即总线频率

POSTDIV:貌似是分频控制,应该是控制FVCO和PLLCLK的分频比,一般设置为0,这时FPLL= FVCO/1=FVCO

初步设想:

1、FVCO= 2*FOSC*(SYNDIV + 1)/(REFDIV + 1),我认为OSC、FOSC、OSCCLK都是一样的,即晶振频率

2、FPLL= FVCO/(2 × POSTDIV),FPLL应该和PLLCLK一样,都是锁相环频率,POSTDIV等于0时默认为分子为1,即FPLL= FVCO/1=FVCO 3、FBUS= FPLL/2,FBUS为总线时钟频率

所以综合起来就有:FBUS=[2*FOSC*(SYNDIV + 1)/(REFDIV + 1)]/2=FOSC*(SYNDIV + 1)/(REFDIV + 1)

再看看龙丘80MHz的超频源代码 void SetBusCLK_80M(void) {

CLKSEL=0X00; //disengage PLL to system PLLCTL_PLLON=1; //开启锁相环

SYNR =0xC0 | 0x09; //我理解,SYNR只是低6位有效,所以经过运算后SYNR=9 REFDV=0x80 | 0x01; //我理解,REFDV只是低4位有效,所以经过运算后REFDV=1 POSTDIV=0x00; //POSTDIV=0x00=0,则FPLL=FVCO=PLLCLK,所以PLLCLK=FVCO=2*16*(1+9)/(1+1)=160MHz;

_asm(nop); //所以总线时钟BUS CLOCK=PLLCLK/2=80MHz _asm(nop);

while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it; CLKSEL_PLLSEL =1; //engage PLL to system; }

好了,个人意见发表完毕,有错误的请更正,别扔砖头哈

砖头我自己仍就行了

synr和refdv都是低6位来设定所要超的频率,其高2位是根据你要超的频率来配置,通过合理的配置VCOFRQ,REFFRQ来提高系统时钟稳定性。具体可以看DATASHEET,如下图:

SYNR =0xC0 | 0x09; //VCOFRQ[7:6]=0b11;SYNDIV[5:0]=0b001001 REFDV=0x80 | 0x01; //REFFRQ[7:6]=0b10;REFDIV[5:0]=0b000001

如:fREF=fOSC/(REFDIV + 1)=16/(1+1)=8;所以6MHz < fREF <= 12MHz REFFRQ[7:6]为10

程序

view plaincopy to clipboardprint?

? /**************************************************************************************

? ------------------------------------ ? Code Warrior 5.0

? Target : MC9S12XS128 ? Crystal: 16.000Mhz

? ============================================ ? 本程序主要包括以下功能: ?

? 设定系统工作在xxMHZ bus clock时钟下; ??

?? by:庞辉

?? *****************************************************************************************/ ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??

#include /* common defines and macros */ #include /* derivative information */ #pragma LINK_INFO DERIVATIVE \

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); ??? } ??? }

本文来源:https://www.bwwdw.com/article/3jq3.html

Top