锁相环PLL及APBDIV
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第十五篇锁相环PLL及APBDIV
关于锁相环的内容早就应该涉及,因为之前的定时器计数周期,和之后的串口波特率、AD转换频率等都与此相关。
锁相环的英文名为:Phase Locked Loop,其实它的作用就是一个倍频器,它把外部晶振频率(Fosc)加倍后得到系统时钟(Fcclk)给CPU使用,即:Fcclk=Fosc*M,这个M值是可设定的,它就是寄存器PLLCFG 的低五位决定,但M值不能随意设定,比如LPC2103的Fcclk不能超过60MHz。
还有一个频率叫Fcco,它是PLL内部的CCO(电流控制振荡器current controlled oscillator)的频率,Fcco=Fcclk*2*P,P由PLLCFG[6:5]决定,我们不要对它有过多注意力,因为外围电路和Fcco无关,CCO 只是为了保证PLL正常工作且在其内部的一个部件(想知道具体机制查相关资料),我们唯一要做的是使Fcco处于正常的范围(LPC2000系列ARM的CCO要求工作在156~320MHz)之内就行了。
还有,Fpclk是我们必须注意的,芯片外设工作于PCLK(APB clock),(APB和AHB是外围电路中的两种总线,AHB速度快,用于VIC;APB用于其它外设:定时器、串口等),PCLK由FCCLK分频得到(通过APB分频器),分频值由寄存器APBDIV[1:0]决定,其它位保留。
上述频率的关系如下图:
下面具体说明程序中应该如何设置这些频率值:
首先说一下这些倍数的配置寄存器:
所谓M由PLLCFG[4:0]决定,并不是二者相等,而是M=PLLCFG[4:0]+1;
还有P=2^PLLCFG[6:5](2的n次幂);
还有:
APBDIV[1:0]=00,Fcclk/Fpclk=1/4;
APBDIV[1:0]=01,Fcclk/Fpclk=1;
APBDIV[1:0]=10,Fcclk/Fpclk=1/2;
APBDIV[1:0]=11,保留。
可以看出M只能取1,2,3……31,32这些值;P只能取1,2,4,8这些值;Fcclk/Fpclk只能取1/4,1/2,1这些值。
再次强调各种频率之间关系:Fcclk=Fosc*M,Fcco=Fcclk*2*P,Fcclk由APBDIV决定Fpclk。
还有它们的取值范围:Fcclk要求不超过60MHz,Fcco要求在156~320MHz范围内。
我们先选定一个晶振频率:Options for Target'…'->Target->Xtal(MHz)->11.0592
方法一:PLL的配置稍微有些复杂,简便起见不自己写PLL的配置代码,在启动代码里已经有相应的代码,打开看看,都是用汇编写的,有些复杂,还好,keil提供一个Configuration Wizard配置向导帮我们轻松修改启动代码,见下图:
轻松修改就完成了。
方法二:编写PLL的C程序:
void PLL_Init()
{
PLLCON = 1; //PLL使能
PLLCFG=5-1|1<<5; //M=PLLCFG[4:0]-1,P=2^PLLCFG[6:5]
PLLFEED = 0xaa; //往PLLFEED依次写0xaa和0x55是为了
PLLFEED = 0x55; //向系统申请对PLLCON和PLLCFG的操作被执行
while((PLLSTAT & (1 << 10)) == 0); //等待PLL的频率锁定,PLLSTAT[10]反映频率锁定情况PLLCON = 3; // PLL使能并连接(接入晶振和系统之间)
PLLFEED = 0xaa;
PLLFEED = 0x55;
}
为了通用性更强点,可以这样写:
void PLL_Init(char M,char P)
{
PLLCON = 1; //PLL使能
switch(P)
{ //M=PLLCFG[4:0]-1,P=2^PLLCFG[6:5]
case 1:PLLCFG=M-1|0<<5;break;
case 2:PLLCFG=M-1|1<<5;break;
case 4:PLLCFG=M-1|2<<5;break;
case 8:PLLCFG=M-1|3<<5;break;
default:break;
}
PLLFEED = 0xaa; //往PLLFEED依次写0xaa和0x55是为了
PLLFEED = 0x55; //向系统申请对PLLCON和PLLCFG的操作被执行
while((PLLSTAT & (1 << 10)) == 0); //等待PLL频率锁定,PLLSTAT[10]反映频率锁定情况PLLCON = 3; // PLL使能并连接(接入晶振和系统之间)
PLLFEED = 0xaa;
PLLFEED = 0x55;
}
对APBDIV的配置很简单,直接赋值就行如“APBDIV=0;”(Fcclk/Fpclk=1/4)
注:LPC2000的外围寄存器上电后,其复位值是0,也就是说清0一般可以省略。
KEIL仿真一下看看:
可见,结果正确。