如需要绘制PCB,设计电路可以和我联系。sunhenu@163.com.
分类: LINUX
2012-04-16 11:01:12
在main函数里,第一句就是TargetResetInit();从函数名可以看出它的主要功能是初始化。
它在target.c中被定义,代码如下:
点击(此处)折叠或打开
MAMCR = 0;设置MAM寄存器的功能
MAMTIM = 1;下面英文说得很明白了,我不想翻译。
PCONP |= 0x80000000; /* Turn On USB PCLK */打开USB外设时钟
#if (Fpclk / (Fcclk / 4)) == 1
PCLKSEL0 = 0x00000000; /* PCLK is 1/4 CCLK */
PCLKSEL1 = 0x00000000;
#endif
#if (Fpclk / (Fcclk / 4)) == 2
PCLKSEL0 = 0xAAAAAAAA; /* PCLK is 1/2 CCLK */
PCLKSEL1 = 0xAAAAAAAA;
#endif
#if (Fpclk / (Fcclk / 4)) == 4
PCLKSEL0 = 0x55555555; /* PCLK is the same as CCLK */
PCLKSEL1 = 0x55555555;
看上面的程序结合下面的图片,就明白了,我不想给大家翻译英文,我相信大家英文水平。
接下来就是ConfigurePLL(); /* Configure PLL, switch from IRC to Main OSC */,注释说得很明白配置PLL。
这个demo程序关于PLL的配置和周立功的例子程序有点不一样,我会一一标注一下的。这里讲的是LPC2378的时钟配置,内容比较多,比较繁琐,但是只要细心耐心的去看程序,我们就会明白LPC2378的时钟工作流程和一些模式。
其实我个人认为学习一个芯片的使用方法,首先就是搞懂它的时钟,这样,你才可以知道各个外设的时钟,才可以计算定时器定时时间,还有UARTIICSPIUSB等等接口的时钟,和相关的分频器的设置,只有时钟设置正确了,我们才可以正常的使用它们,设置好时钟是第一步。
我们就看看这个函数的具体内容是什么。它也定义在target.c中。
点击(此处)折叠或打开
if ( PLLSTAT & (1 << 25) )
{
PLLCON = 1; /* Enable PLL, disconnected */
PLLFEED = 0xaa;
PLLFEED = 0x55;
}
首先看看PLLSTAT这个状态寄存器所代表的意思。
PLLCON寄存器代表的意思
PLLCON = 1;就是PLLE=1;
PLLFEED = 0xaa;
PLLFEED = 0x55;
这两句,很简单,但是不可以少。呵呵。
到这里我们就是知道这个IF语句的功能了就是说,如果芯片上电以后,PLL有效并且供给CPU时钟的话,那么使得PLL有效,但是不给CPU供给时钟,bypass,呵呵。
PLLCON = 0; /* Disable PLL, disconnected */
PLLFEED = 0xaa;
PLLFEED = 0x55;
使得PLL无效,当然了也不供给cpu时钟。
SCS |= 0x20; /* Enable main OSC */
while( !(SCS & 0x40) ); /* Wait until main OSC is usable */
CLKSRCSEL = 0x1; /* select main OSC, 12MHz, as the PLL clock source */
注释说得很明白了,但是我还是要重复一下,先看SCS寄存器。
PLLCFG = PLL_MValue | (PLL_NValue << 16);
PLLFEED = 0xaa;
PLLFEED = 0x55;
在PLLCFG寄存器说明中提到M和N的这个2个变量,我们具体看一下它们代表什么意思。
在target.h中的一些宏定义。
CCLKCFG = CCLKDivValue; /* Set clock divider */
从上面宏定义中的M和N的值我们可以计算出Fcco=2X12X(24+1)/(1+1)=300,单位MHZ.
Fcclk=Fcco/(5+1)=50MHZ.和上面宏定义的一样。接下来就是检测当前设定的M和N的值是否已经被PLL采用,开始工作了。否则,就是PC指针就一直在while处等待。
while ( ((PLLSTAT & (1 << 26)) == 0) ); /* Check lock bit status */
MValue = PLLSTAT & 0x00007FFF;
NValue = (PLLSTAT & 0x00FF0000) >> 16;
如果正常,保持实际的M和N值,然后和预设的M和N值对比,相同,就使能PLL并连接PLL到cpu。否则就等待。
while ((MValue != PLL_MValue) && ( NValue != PLL_NValue) );
PLLCON = 3; /* enable and connect */
PLLFEED = 0xaa;
PLLFEED = 0x55;
查询PLL是否连接,没有,就等待。
while ( ((PLLSTAT & (1 << 25)) == 0) ); /* Check connect bit status */
return;
到这里PLL配置讲完了,下面补充一些PLL的东西。
这是LPC2378时钟示意图,中间涉及了各个时钟之间的关系,想明白时钟系统,必须知道这个示意图。
还有就是我一直没有找到相关信息,就是在这个demo程序里提到cpu时钟不可以超过80MHZ,周立功的程序也提到了这个80MHZ,我在lpc2378datasheet没有找到相关的东西,只是找到了这个
难道写程序的人是为了凑个整数?
对了还有,就是周立功程序中间还提到了使用中断方式设置PLL,这里就不多说了,自己可以去参考一下,周立功的程序中Fin=12M,M=12,N=1,Fcco=2X12X12/1=288M,Fcclk=72M.
这里的M和N在使用的时候,我没有加1,原因是,周立功程序,在把M,N赋值给寄存器的时候减去1,也就是把M-1,N-1赋值给了寄存器,所以这里计算频率就是M和N的值了,
这个demo程序直接把M和N赋值给了寄存器,所以计算频率的时候就需要加1了。