修改ARM7之PLL设定以优化系统性能
<前言>
当我们设计 ARM7 的系统, 除非我们不使用PLL(系统运行频率即为晶振频率), 否则我们不可避免要和PLL倍率打交道.
设计PLL设定, 我们搜索网路, 经常见到的参考例程是:
1. 频率设定:
//// system settings, Fosc、Fcclk、Fcco、Fpclk
#define Fosc 11059200
#define Fcclk (Fosc * 4)
#define Fcco (Fcclk * 4)
#define Fpclk (Fcclk/4) * 1
2. PLL设定:
void pll_init(void)
{
PLLCON = 1; // enable PLL but not connecting it
//// VPBDIV
// Fpclk: Fpclk=N*(Fcclk/4)
#if ((Fcclk / 4) / Fpclk) == 1
VPBDIV = 0;
#endif
#if ((Fcclk / 4) / Fpclk) == 2
VPBDIV = 2;
#endif
#if ((Fcclk / 4) / Fpclk) == 4
VPBDIV = 1;
#endif
//// PLLCFG
// Pcclk: Fcclk=M*Posc
// Pcco: Fcco=2P*Fcclk
#if (Fcco / Fcclk) == 2
PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5);
#endif
#if (Fcco / Fcclk) == 4
PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5);
#endif
#if (Fcco / Fcclk) == 8
PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5);
#endif
#if (Fcco / Fcclk) == 16
PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5);
#endif
PLLFEED = 0xaa; // realize setting
PLLFEED = 0x55; // realize setting
while((PLLSTAT & (1 << 10)) == 0); // waiting for PLL lock
PLLCON = 3; // enable PLL and do connection
PLLFEED = 0xaa; // realize setting
PLLFEED = 0x55; // realize setting
}
网路上例程资源, 常常还附上这样的话语: (PLL设定)"一般不需要修改".
本文的目的, 就是要对 PLL 设定进行修改, 到达我们优化系统运行速度之目的.
<知识准备>
1. 频率概念:
(1) Fosc: 晶振频率. 一般取 11.0592MHz 的目的, 是分频后准确套入一般的串口通讯之波特率.
(2) Fcclk: 系统时钟频率. lpc21xx 取 Fosc 的[1, 32] 倍频, 最大频率不可超过 60MHz.
(3) Fcco: 电流控制振荡器频率. 假设其为 PLL 倍频过程中必要使用频率, datasheet 约定为 Fcclk 的4, 8, 16倍.
(4) Fpclk: VPB 之时钟频率. VPB为 lpc21xx 之外围总线(Peripheral Bus).
2. PLL设定寄存器:
(1) VPBDIV: 设定 Fpclk.
(2) PLLCFG: 设定 Fcclk 与 Fcco.
<优化目的>
在我们设计的一个应用中, 存在着 200us 的扫描任务, 任务包含 access spi flash. 一个质朴的思路是, 提高系统运行频率以及spi访问时间.
<修改PLL设定>
1. 频率修改:
//// system settings, Fosc、Fcclk、Fcco、Fpclk
#define Fosc 11059200
#define Fcclk (Fosc * 5)
#define Fcco (Fcclk * 4)
#define Fpclk (Fcclk/4) * 4
2. 原始PLL设定下系统表现:
(1) 晶振频率 Fosc ~= 11MHz
(2) 系统频率 Fcclk ~= 44MHz
(3) VPB频率 Fpclk ~= 11MHz
3. 修改PLL设定的系统表现:
(1) 晶振频率 Fosc ~= 11MHz
(2) 系统频率 Fcclk ~= 55MHz
(3) VPB频率 Fpclk ~= 55MHz
故, 系统时钟频率 Fcclk' = (5/4)*Fcclk, 增加为 5/4 倍.
VPB频率 Fpclk' = 5*Fpclk, 增加为 5倍.
<系统框图>
分析框图得知,
我们假设系统程序运行速度增加为, 原速度的 5/4 倍.
我们假设 GPIO 速度, IIC, SPI 读写速度, 以及定时器速度, 软件狗(WDI)速度, 串口读写速度等增加为, 原速度的 5倍.
<验证>
1. 我们验证软件狗WDI, 速度加快5倍, 验证过程:
void wdt_init(void)
{
WDTC = (Fosc/4)*3; // wdt timeout value(Fosc/4 is 1s)
WDMOD = 0x03; // watchdog reset mode
wdt_feed_event(); // start and feed wdt
}
需要修改为:
void wdt_init(void)
{
WDTC = (Fpclk/4)*3; // wdt timeout value(Fpclk/4 is 1s)
WDMOD = 0x03; // watchdog reset mode
wdt_feed_event(); // start and feed wdt
}
2. 我们验证定时器速度加快 5倍. 验证过程不表, 下面的MC有修改:
T0MR0 = 55295;
修改为:
T0MR0 = 55295*5;
3. SPI的5倍加快, 没有技术验证.
用不严谨的表述是, 我们感觉 spi access flash 在 200us 的扫描application中, 不再成为一个导致延时的任务.
4. GPIO 的5倍加快. 我们因为使用了 FPIO, 对普通的 IO 读写速度的 5倍加快, 故没有验证.
5. 处理器执行速度增加 5/4倍(55MHz), 验证过程:
void delay_ms(U32 ms)
{
for(U32 i=0; i U32 clk = 7377; // 1000
while(clk--);
}
}
修改为:
void delay_ms(U32 ms)
{
for(U32 i=0; i U32 clk = (7377*5)>>2; // 1000
while(clk--);
}
}
<结论>
常见的设定, 让 arm7 的系统时钟跑在 44M, 让外围总线时钟跑在 11M, 并不建议使用者更改.
Allen 通过工程验证得知, 设定系统时钟为 55M, 并设定 peripheral bus 时钟为 55M.
将导致系统的代码执行速度增加 5/4 倍, 以及 gpio/adi/spi/iic/timer/wdi 等应用速度, 增加 5倍.
考虑到这样的 PLL 设定仍然在 datasheet 手册范围中, 对于功耗少许增加不敏感的高速扫描应用应用,
或高速外围如flash的acess 等应用, 我们找不到该PLL设定不合适的理由.
<参考资料>
1. nxp lpc21xx datasheet
2. LPC21XX与LPC22XX时钟频率(http://www.how138.com/news.asp?id=514)
Allen Zhan
2011.01.23
发表于<电子工程专辑>
文章评论(0条评论)
登录后参与讨论