要对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进行基本的时钟配置,为后续程序提供保障。
上一篇:时钟配置的仿真
下一篇:LPC11XX.h头文件解析
推荐阅读最新更新时间:2024-03-16 15:06
设计资源 培训 开发板 精华推荐
- ADI 系统方案精选【用于多路抽头输出隔离电源的简易解决方案】
- PI有奖问答之聚焦PI InnoSwitch-CH
- 骏龙科技&ADI有奖直播:适用于视频、转换器、通信的千兆数字隔离器
- 有奖直播:新科技、新课堂、新学期~ ADI软件定义无线电ADALM-Pluto入门实战
- Discover mmWave 走进 TI 毫米波雷达世界 快速获得设计技能
- TI无线产品调查问卷,好礼轻松拿!
- 【EEWORLD大学堂】玩转LaunchPad及TI MSP430G2XX系列超值单片机!!!
- 泰克70周年庆 了解新品 参与掀盖有礼活动 最多可获得6次抽奖机会
- 【泰有聊】第二期:泰克CEO为你解读低噪声背后的科学
- 今日直播 | 西门子半导体行业数字主线串享未来