要让LPC1114正常作业,首要要对它的时钟源进行装备。LPC1114的最高作业频率为50MHz,因而给它的主时钟频率最大不能超过50MHz。实际上,一般都是运用频率较低的晶振,以下降外部电磁搅扰,然后再经过内部倍频的方法把主时钟频率进步。依据管方手册给出的数据,外部晶振的频率规模是1MHz~25MHz,一般情况下运用12MHz晶振,然后内部进行4倍频,主时钟作业频率为48MHz。
要对LPC1114的时钟进行装备,有必要要了解它的时钟结构,先来看一下它的时钟结构图,如下图所示。

首要来看主时钟,给主时钟(main clock)供应挑选有4个源,分别是:内部RC振动器、未倍频之前的PLL时钟、内部看门狗时钟、经过PLL倍频之后的时钟。由对主时钟源挑选寄存器(MAINCLKSEL)的操作来进行挑选,同一时间只能挑选一种时钟做为主时钟。下面就给出MAINCLKSEL寄存器的位结构(要留意,因为LPC1114是32位的,所以一切的寄存器都是32位的),如下表所示。
位 |
符号 |
值 |
描绘 |
复位值 |
1∶0 |
SEL |
00 |
内部RC振动器 |
0x00 |
01 |
PLL倍频之前的时钟 |
|||
10 |
内部看门狗时钟 |
|||
11 |
PLL倍频之后的时钟 |
|||
31∶2 |
– |
– |
保存 |
0x00 |
前面说过,一般情况下CPU内部都是要进行倍频的,因而大多数时分该寄存器的值都会挑选11(0x03),履行句子“SYSCON->MAINCLKSEL=0x00000003”就能够了。
接下来看体系PLL时钟,PLL便是频率锁相环的意思,PLL的功用许多,有爱好的可自行参阅其它材料,这儿首要利用它来完结倍频的功用。从上图中能够看出,供应PLL挑选的有2个源,一个是片内RC振动器,另一个是晶体振动器。由对体系PLL时钟挑选寄存器(SYSPLLCLKSEL)的操作来进行挑选,同一时间只能挑选一种时钟做为输入时钟。下面给出SYSPLLCLKSEL寄存器的位结构,如下表所示。
位 |
符号 |
值 |
描绘 |
复位值 |
1∶0 |
SEL |
00 |
内部RC振动器 |
0x00 |
01 |
晶体振动器 |
|||
10 |
保存 |
|||
11 |
保存 |
|||
31∶2 |
– |
– |
保存 |
0x00 |
一般情况下,为了进步时钟精度都会挑选01(0x01),以挑选外部晶体振动器做为时钟输入。履行句子“SYSCON->SYSPLLCLKSEL=0x00000001”就能够了。
在时钟结构图中还能够看出,主时钟分红6路供应不同的模块。其间一路主时钟经过体系时钟分频器(SYSAHBCLKDIV)后做为体系时钟,供应给AHB。在LPC1114中,只要通用输入输出端口(GPIO)需求AHB。为了给不同速度的模块(如内核、存储器、APB等)供应时钟,需求对SYSAHBCLKDIV寄存器进行操作,以对主时钟进行分频。下面给出SYSAHBCLKDIV寄存器的位结构,如下表所示。
位 |
符号 |
值 |
描绘 |
复位值 |
7∶0 |
DIV |
00000000 |
关闭体系时钟 |
0x01 |
00000001 |
1 |
|||
00000010 |
2 |
|||
…… |
…… |
|||
11111111 |
255 |
|||
31∶8 |
– |
– |
保存 |
0x00 |
由上述可见,居于Cotex-M0内核的CPU因为强化了时钟装备,所以在一般情况下要运用该类型的CPU,首要的使命便是为其装备正确的时钟。下面就来讨论一下怎么经过程序来装备LPC1114的时钟。
先给出一个时钟初始化的函数,如下:
void SysCLK_config(void)
{
uint8_t i;
LPC_SYSCON->PDRUNCFG &= ~(1 << 5); //给体系振动器上电
LPC_SYSCON->SYSOSCCTRL = 0x00000000; //体系振动器未旁路,1~12MHz输入
for (i = 0; i < 200; i++) __nop(); //延时等候振动器安稳
LPC_SYSCON->SYSPLLCLKSEL = 0x00000001; //PLL输入挑选外部晶体振动
LPC_SYSCON->SYSPLLCLKUEN = 0x00;
LPC_SYSCON->SYSPLLCLKUEN = 0x01; //先写0后写1更新时钟源
while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); //等候更新完结
LPC_SYSCON->SYSPLLCTRL = 0x00000013; //M=4、P=2,倍频后的时钟为48MHz
LPC_SYSCON->PDRUNCFG &= ~(1 << 7); //给PLL上电
while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); //等候PLL确认
LPC_SYSCON->MAINCLKSEL = 0x00000003; //主时钟挑选PLL倍频后的时钟
LPC_SYSCON->MAINCLKUEN = 0x00;
LPC_SYSCON->MAINCLKUEN = 0x01; //先写0后写1更新时钟源
while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); //等候更新完结
LPC_SYSCON->SYSAHBCLKDIV = 0x00000001; //AHB为1分频,AHB时钟为48MHz
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); //使能GPIO时钟
}
假如运用的是12MHz的外部晶振,该函数履行完后,LPC1114的时钟被设置成为主时钟48MHz,AHB时钟48MHz,输入输出端口(GPIO)时钟使能的状况。
在上述程序中,PLL输入挑选寄存器(SYSPLLCLKSEL),主时钟挑选寄存器(MAINCLKSEL),AHB分频挑选寄存器(SYSAHBCLKDIV)均在前面讨论过,下面来看一下没讨论过的寄存器。先看“掉电装备寄存器(PDRUNCFG)”,下表是它的位结构。
位 |
符号 |
值 |
描绘 |
复位值 |
0 |
IRCOUT_PD (IRC振动器输出掉电) |
1 |
掉电 |
0 |
0 |
上电 |
|||
1 |
IRC_PD (IRC振动器掉电) |
1 |
掉电 |
0 |
0 |
上电 |
|||
2 |
FLASH_PD (Flash掉电) |
1 |
掉电 |
0 |
0 |
上电 |
|||
3 |
BOD_PD (BOD掉电) |
1 |
掉电 |
0 |
0 |
上电 |
|||
4 |
ADC_PD (ADC掉电) |
1 |
掉电 |
1 |
0 |
上电 |
|||
5 |
SYSOSC_PD (体系振动器掉电) |
1 |
掉电 |
1 |
0 |
上电 |
|||
6 |
WDTOSC_PD (看门狗振动器掉电) |
1 |
掉电 |
1 |
0 |
上电 |
|||
7 |
SYSPLL_PD (体系PLL掉电) |
1 |
掉电 |
1 |
0 |
上电 |
|||
8 |
– |
– |
保存 |
1 |
9 |
– |
0 |
保存,置0 |
0 |
10 |
– |
– |
保存 |
1 |
11 |
– |
1 |
保存,置1 |
1 |
12 |
– |
0 |
保存,置0 |
0 |
15∶13 |
– |
– |
保存 |
1 |
31∶16 |
– |
– |
保存 |
从表中能够看出,体系振动器和体系PLL在默许情况下是掉电的,也便是说默许它们不处于作业状况,要让它们作业就有必要给它们置0上电。所以要经过履行句子“SYSCON->PDRUNCFG &= ~(1 << 5)”和“SYSCON->PDRUNCFG &= ~(1 << 7)”来把SYSOSC和SYSPLL置0。
接下来看“体系振动器操控寄存器(SYSOSCCTRL)”,下表是它的位结构。
位 |
符号 |
值 |
描绘 |
复位值 |
0 |
BYPASS (旁路体系振动器) |
0 |
未被旁路 |
0 |
1 |
被旁路 |
|||
1 |
FREQRANGE (低功耗振动器确认频率规模) |
0 |
1~20MHz |
0 |
1 |
15~25MHz |
|||
31∶2 |
– |
– |
保存 |
0 |
从表中能够看出,假如要让体系振动器作业,则其第0位就应该挑选0,即不被旁路,只要在从外部直接输入振动信号的情况下才会挑选旁路(比方运用有源晶振)。第1位用于挑选外部晶振的频率规模,运用12MHz时该位挑选0。履行句子“SYSCON->SYSOSCCTRL = 0x00000000”就能够完结上述装备,但实际上复位后的值便是该装备,也可不履行该句子。
从上述程序中还能够看出,在装备了时钟后(无论是PLL时钟仍是主时钟),都需求更新一下才干正常作业。而更新的操作则依据管方手册,有必要要给相应的答应寄存器“toggle”一下(即先向其写0再紧接着写1)。“体系PLL时钟源更新答应寄存器(SYSPLLCLKUEN)”和“主时钟源更新答应寄存器(MAINCLKUEN)”的位结构是相同的,下表是MAINCLKUEN寄存器的位结构。
位 |
符号 |
值 |
描绘 |
复位值 |
0 |
ENA (答应主时钟源更新) |
0 |
无变化 |
0 |
1 |
更新时钟源 |
|||
31∶1 |
– |
– |
保存 |
0 |
在主时钟源及PLL时钟源更改后,要紧接着及时更新相应的答应寄存器才干让其正常作业。此外还要留意一点,“toggle”后需求查询相应的答应寄存器是否已更新,若没有就需求等候直到其更新停止(例如在更新PLL时钟源更新答应寄存器SYSPLLCLKUEN后要履行句子“while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01));”,以等候其更新完结)。
接下来看一下PLL的装备,要让PLL对输入时钟进行倍频或分频,就要装备“体系倍频操控寄存器(SYSPLLCTRL)”,下表是该寄存器的位结构。
位 |
符号 |
值 |
描绘 |
复位值 |
4∶0 |
MSEL (反应分频器的值, 分频器的值M是MSEL+1) |
00000 |
M=1 |
0x00 |
…… |
…… |
|||
11111 |
M=32 |
|||
6∶5 |
PSEL (后分频器的值, 分频器的值为2×P) |
00 |
P=1 |
0x00 |
01 |
P=2 |
|||
10 |
P=4 |
|||
11 |
P=8 |
|||
31∶7 |
– |
– |
保存,不能写1 |
0x00 |
PLL的输出频率要契合下面的公式。

Fclkout为PLL的输出频率,Fclkin为外部晶振的频率,FCCO的值有必要在156MHz ~320MHz之间,M为倍频的倍数,P值要契合要求。若以12MHz的晶振做为输入,体系主时钟要为48MHz,则M=4(MSEL=0011),P的值只能取2(PSEL=01)才干满意公式要求。因而寄存器SYSPLLCTRL的值应该为10011(0x13),所以要装备此项只需求履行句子“SYSCON->SYSPLLCTRL = 0x00000013”就能够了。
在改变了PLL的倍频之后,需求查询“倍频状况寄存器(SYSPLLSTAT)”,看PLL确认了没有,若没有就需求等候直到其确认停止(履行句子“while (!(LPC_SYSCON->SYSPLLSTAT & 0x01));”)。下面是“倍频状况寄存器(SYSPLLSTAT)”的位结构。
位 |
符号 |
值 |
描绘 |
复位值 |
0 |
LOCK (PLL确认状况) |
0 |
未确认 |
0 |
1 |
已确认 |
|||
31∶1 |
– |
– |
保存 |
0 |
CPU要对GPIO进行操作,就有必要给GPIO时钟信号,即需求使能GPIO的时钟。在默许情况下GPIO时钟是答应的,也能够对“体系AHB时钟操控寄存器(SYSAHBCLKCTRL)”中相应的位进行操作来挑选答应时钟,下面是该寄存器的位结构。
位 |
符号 |
值 |
描绘 |
复位值 |
0 |
SYS (答应AHB时钟,只读) |
0 |
保存 |
1 |
1 |
答应 |
|||
1 |
ROM (答应ROM时钟) |
0 |
制止 |
1 |
1 |
答应 |
|||
2 |
RAM (答应RAM时钟) |
0 |
制止 |
1 |
1 |
答应 |
|||
3 |
FLASHREG (答应flash寄存器接口时钟) |
0 |
制止 |
1 |
1 |
答应 |
|||
4 |
FLASHARRAY (答应flash阵列存取时钟) |
0 |
制止 |
1 |
1 |
答应 |
|||
5 |
I2C (答应I2C时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
6 |
GPIO (答应GPIO时钟) |
0 |
制止 |
1 |
1 |
答应 |
|||
7 |
CT16B0 (答应16位计数/定时器0时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
8 |
CT16B1 (答应16位计数/定时器1时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
9 |
CT32B0 (答应32位计数/定时器0时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
10 |
CT32B1 (答应32位计数/定时器1时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
11 |
SSP0 (答应SPI0时钟) |
0 |
制止 |
1 |
1 |
答应 |
|||
12 |
UART (答应UART时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
13 |
ADC (答应ADC时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
14 |
– |
– |
保存 |
0 |
15 |
WDT (答应WDT时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
16 |
IOCON (答应IO装备模块时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
17 |
– |
– |
保存 |
0 |
18 |
SSP1 (答应SPI1时钟) |
0 |
制止 |
0 |
1 |
答应 |
|||
31∶19 |
– |
– |
保存 |
0x00 |
从表中能够看出,第6项便是“通用输入输出端口”的时钟装备项,履行句子“SYSCON->SYSAHBCLKCTRL |= (1<<6)”就能够敞开GPIO的时钟。在翻开了GPIO的时钟后,就能够运用P0~P3端口了。
上述的时钟装备程序是最根本的,也是有必要的,因而在任何程序开端前,都应该先调用该时钟装备函数,以对LPC1114进行根本的时钟装备,为后续程序供应保证。