LPC824-时钟配置

发布时间:2023-05-25  

要让LPC824正常工作,首先要对它的时钟源进行配置。LPC824的最高工作频率为30MHz,因此给它的主时钟频率最大不能超过30MHz。实际上,通常都是使用频率较低的晶振,以降低外部电磁干扰,然后再通过内部倍频的方式把主时钟频率提高。根据管方手册给出的数据,外部晶振的频率范围是1MHz~25MHz,一般情况下使用12MHz晶振,然后内部进行2倍频,主时钟工作频率为24MHz。
要对LPC824的时钟进行配置,必须要了解它的时钟结构,先来看一下它的时钟结构图,如下图所示。

首先来看主时钟,给主时钟(main clock)提供选择有4个源,分别是:内部RC振荡器、未倍频之前的PLL时钟、内部看门狗时钟、经过PLL倍频之后的时钟。由对主时钟源选择寄存器(MAINCLKSEL)的操作来进行选择,同一时刻只能选择一种时钟做为主时钟。

下表给出了主时钟源选择寄存器MAINCLKSEL的全部位结构,其字节地址为0x40048070。注意,由于LPC824是32位微控制器,所以它内部的寄存器全都是32位的。 

(1)第0、1两位(SEL)为主时钟源选择位,这两位的值从0x0到0x3,分别对应选择内部RC时钟、未倍频之前的PLL时钟、内部看门狗时钟、经过PLL倍频之后的时钟。
(2)第2到31位为保留位。
一般情况下都会选择系统PLL倍频后的时钟作为主时钟,因此大多数时候MAINCLKSEL寄存器的值都会选择0x3(执行语句“LPC_SYSCON->MAINCLKSEL=0x00000003”)。
接下来看系统PLL时钟,PLL(Phase Locked Loop)即锁相环,它的功能很多,这里主要利用它来实现倍频的功能。从时钟结构图中可以看出,供给PLL选择的有3个源,一个是片内RC振荡器,另一个是系统振荡器,再一个是外部输入。通过对系统PLL时钟选择寄存器的操作可进行选择,但同一时刻只能选择一种时钟作为输入时钟。
下表给出了系统PLL时钟选择寄存器SYSPLLCLKSEL的全部位结构,其字节地址为0x40048040。

(1)第0、1两位(SEL)为系统PLL时钟源选择位,值为0x0时选择内部RC时钟,值为0x1时选择系统振荡时钟(即外部晶振),值为0x3时选择外部时钟输入,其他值为保留。
(2)第2到31位为保留位。
为了提高LPC824的时钟精度,一般情况下SYSPLLCLKSEL寄存器的值会选择0x1(执行语句“LCP_SYSCON->SYSPLLCLKSEL=0x00000001”),以选择外部晶体振荡器作为时钟输入。
从时钟结构图中可以看到,主时钟分成4路供给不同的模块。其中一路主时钟经过系统AHB时钟分频选择(SYSAHBCLKDIV)后作为系统时钟提供给AHB。在LPC824中,只有高速设备(如GPIO、SRAM等)才需要AHB。为了给不同速度的模块(如内核、存储、APB等)提供时钟,需要对系统AHB时钟分频选择寄存器进行操作,以对主时钟进行分频。
下表给出了系统AHB时钟分频选择寄存器SYSAHBCLKDIV的全部位结构,其字节地址为0x40048078。

(1)第0到7位(DIV)为系统AHB时钟选择位,值为0时禁止系统时钟,其他值为AHB时钟的分频值。
(2)第8到31位为保留位。
从表中可以看到,AHB时钟分频的最大值为255。系统的默认值为1(也可执行语句“LPC_SYSCON->SYSAHBCLKDIV=0x00000001”来实现),即为AHB提供不分频的主时钟。剩余3个模块(USART、IOCON、CLKOUT)的时钟也一样由主时钟来分频,只不过它们默认的分频值为0,即默认不提供时钟,也就是说剩余的3个模块在默认状态下不工作,需要的时候再通过程序打开,以降低功耗。

下表给出的是掉电配置寄存器PDRUNCFG的全部位结构,其字节地址为0x40048238。

 

(1)第0位(IRCOUT_PD)为内部RC振荡器输出掉电控制位,置0时上电,置1时掉电,默认为上电。
(2)第1位(IRC_PD)为内部RC振荡器掉电控制位,置0时上电,置1时掉电,默认为上电。
(3)第2位(FLASH_PD)为FLASH掉电控制位,置0时上电,置1时掉电,默认为上电。
(4)第3位(BOD_PD)为BOD掉电控制位,置0时上电,置1时掉电,默认为上电。
(5)第4位(ADC_PD)为ADC掉电控制位,置0时上电,置1时掉电,默认为掉电。
(6)第5位(SYSOSC_PD)为系统振荡器掉电控制位,置0时上电,置1时掉电,默认为掉电。
(7)第6位(WDTOSC_PD)为看门狗振荡器掉电控制位,置0时上电,置1时掉电,默认为掉电。
(8)第7位(SYSPLL_PD)为系统PLL掉电控制位,置0时上电,置1时掉电,默认为掉电。
(9)第8到14位为保留位,但它们有默认值,在对这些位进行写入操作时,必须按照默认值来写。
(10)第15位(ACMP)为模拟比较器掉电控制位,置0时上电,置1时掉电,默认为掉电。
(11)第16到31位为保留位。
从上表中可以看出,系统振荡器和系统PLL在默认情况下是掉电的,也就是说默认状态下它们处于不工作状态,要让它们工作就必须给它们的控制位置0(执行语句“LPC_SYSCON->PDRUNCFG &= ~(1 << 5)”和“LCP_SYSCON->PDRUNCFG &= ~(1 << 7)”),以更改为上电状态。

下表给出了系统振荡器控制寄存器SYSOSCCTRL的全部位结构,其字节地址为0x40048020。


(1)第0位(BYPASS)为系统振荡器旁路控制位,置0时未旁路,置1时被旁路,默认为未旁路。
(2)第1位(FREQRANGE)为低功耗振荡器确定频率范围选择位,置0时外部晶振的频率范围为1~20MHz,置1时为15~20MHz,默认为1~20MHz。
(3)第2到31位为保留位。
从上表中可以看出,如果要让系统振荡器工作,则SYSOSCCTRL寄存器的第0位就应该选择0,即不被旁路,只有从外部直接输入振荡信号的情况下才会选择旁路(比如使用有源晶振)。若系统使用12MHz外部晶振,则第1位应该选择0。实际上LPC824复位后的值就是该配置值,当然也可执行语句“LCP_SYSCON->SYSOSCCTRL = 0x00000000”来实现。
在配置了LPC824的时钟之后(无论是PLL时钟还是主时钟),都需要“更新”一下才能正常工作。根据官方数据手册,更新操作要给相应的更新允许寄存器进行“toggle”操作(即先向其写0再紧接着写1),这样之后时钟才能正常运行。
以下两表分别给出了系统PLL时钟源更新允许寄存器SYSPLLCLKUEN和主时钟源更新允许寄存器MAINCLKUEN的全部位结构,它们的字节地址分别为0x40048044、0x40048074。

(1)第0位(ENA)为允许系统PLL时钟源更新控制位,置0时无变化,置1时更新,默认为无变化。
(2)第1到31位为保留位。

(1)第0位(ENA)为允许主时钟源更新控制位,置0时无变化,置1时更新,默认为无变化。
(2)第1到31位为保留位。

在PLL时钟源和主时钟源更改后,紧接着要及时更新相应的允许寄存器才能让它们正常工作。此外还要注意,“toggle”后需要再次查询相应的允许寄存器是否已更新,若没有就需要等待直到其更新为止(例如在更新PLL时钟源更新允许寄存器SYSPLLCLKUEN后要执行语句“while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01));”,以等待其更新完成)。
接下看PLL的配置,要让PLL对输入时钟进行倍频或分频,就得配置系统倍频控制寄存器,下表给出了系统倍频控制寄存器SYSPLLCTRL的全部位结构,其字节地址为0x40048008。

 

(1)第0到4位(MSEL)为反馈分频器的值,分频器的值M为MSEL+1。
(2)第5、6两位(PSEL)为后分频器的值,分频器的值为2×P。
(3)第7到31位为保留位,不能对它们写1。
PLL的输出频率要符合下面的公式:

上式中,Fclkout为PLL的输出频率,Fclkin为外部晶振的频率,FCCO的值必须在156MHz ~320MHz之间,M为倍频的倍数,P值要符合要求。若以12MHz的晶振做为输入,系统主时钟要为24MHz,则M=2(MSEL=00001),P的值只能取4(PSEL=10)才能满足公式要求。因此寄存器SYSPLLCTRL的值应该为1000001(0x41),所以要配置此项可执行语句“LPC_SYSCON->SYSPLLCTRL = 0x00000041”。
下表给出了倍频状态寄存器SYSPLLSTAT的全部位结构,其字节地址为0x4004800C。

 

(1)第0位(LOCK)为PLL锁定状态标志位,为0时未锁定,为1时锁定。
(2)第1到31位为保留位。
在改变了PLL的倍频之后,要查询SYSPLLSTAT寄存器来确定PLL锁定了没有,若没有就进入等待直到其锁定为止(执行语句“while (!(LPC_SYSCON->SYSPLLSTAT & 0x01));”)。
CPU要对GPIO进行操作,就必须给GPIO时钟信号,即需要使能GPIO的时钟。在默认情况下GPIO时钟是允许的,也可以对系统AHB时钟控制寄存器中相应的位进行操作来选择允许时钟。
下表给出了系统AHB时钟控制寄存器SYSAHBCLKCTRL的全部位结构,其字节地址为0x40048080。

  

(1)第0位(SYS)为允许AHB时钟标志位,该位为只读,值为0时保留,为1时允许,默认为允许。
(2)第1位(ROM)为允许ROM时钟控制位,置0时禁止,置1时允许,默认为允许。
(3)第2位(RAM0_1)为允许SRAM0和SRAM1时钟控制位,置0时禁止,置1时允许,默认为允许。
(4)第3位(FLASHREG)为允许flash寄存器接口时钟控制位,置0时禁止,置1时允许,默认为允许。
(5)第4位(FLASH)为允许flash时钟控制位,置0时上电禁止,置1时允许,默认为允许。
(6)第5位(I2C0)为允许I2C0时钟控制位,置0时禁止,置1时允许,默认为禁止。
(7)第6位(GPIO)为允许GPIO时钟控制位,置0时禁止,置1时允许,默认为允许。
(8)第7位(SWM)为允许开关矩阵时钟控制位,置0时禁止,置1时允许,默认为允许。
(9)第8位(SCT)为允许配置SCTimer/PWM时钟控制位,置0时禁止,置1时允许,默认为禁止。
(10)第9位(WKT)为允许自唤醒定时器时钟控制位,置0时禁止,置1时允许,默认为禁止。
(11)第10位(MRT)为允许多速率定时器时钟控制位,置0时禁止,置1时允许,默认为禁止。
(12)第11位(SPI0)为允许SPI0时钟控制位,置0时禁止,置1时允许,默认为禁止。
(13)第12位(SPI1)为允许SPI1时钟控制位,置0时禁止,置1时允许,默认为禁止。
(14)第13位(CRC)为允许CRC时钟控制位,置0时禁止,置1时允许,默认为禁止。
(15)第14位(UART0)为允许USART0时钟控制位,置0时禁止,置1时允许,默认为禁止。
(16)第15位(UART1)为允许USART1时钟控制位,置0时禁止,置1时允许,默认为禁止。
(17)第16位(UART2)为允许USART2时钟控制位,置0时禁止,置1时允许,默认为禁止。
(18)第17位(WWDT)为允许WWDT时钟控制位,置0时禁止,置1时允许,默认为禁止。
(19)第18位(IOCON)为允许IOCON时钟控制位,置0时禁止,置1时允许,默认为禁止。
(20)第19位(ACMP)为允许模拟比较器时钟控制位,置0时禁止,置1时允许,默认为禁止。
(21)第20位为保留位。
(22)第21位(I2C1)为允许I2C1时钟控制位,置0时禁止,置1时允许,默认为禁止。
(23)第22位(I2C2)为允许I2C2时钟控制位,置0时禁止,置1时允许,默认为禁止。
(24)第23位(I2C3)为允许I2C3时钟控制位,置0时禁止,置1时允许,默认为禁止。
(25)第24位(ADC)为允许ADC时钟控制位,置0时禁止,置1时允许,默认为禁止。
(26)第25位为保留位。
(27)第26位(MTB)为允许微跟踪缓冲区控制寄存器时钟控制位,置0时禁止,置1时允许,默认为禁止。
(28)第27、28两位为保留位。
(29)第29位(DMA)为允许DMA时钟控制位,置0时禁止,置1时允许,默认为禁止。
(30)第30、31两位为保留位。

从上表中可以看出,第6位即为“通用输入输出端口GPIO”的时钟配置项,执行语句“LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6)”就可以开启GPIO的时钟。在打开了GPIO的时钟后,PIO0_0~PIO0_28端口才能正常使用,不过默认状态就是开启的。

由上述可见,基于Cortex-M0+内核的微控制器由于强化了时钟配置,所以在一般情况下使用该类型的芯片,首要的任务就是配置正确的时钟。
下面给出一个时钟初始化的配置函数,可通过它来了解LPC824时钟配置的整个过程。
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->SYSAHBCLKCTRL |= (1 << 18);  //使能IOCON时钟
 LPC_IOCON->PIO0_8 &= ~(3 << 3);          //把P0_8引脚配置为无上下拉电阻方式
  LPC_IOCON->PIO0_9 &= ~(3 << 3);          //把P0_9引脚配置为无上下拉电阻方式
  LPC_SWM->PINENABLE0 &= ~(3 << 6);     //把P0_8、P_9引脚配置为XTALIN、XTALOUT引脚
 LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 18);  //禁止IOCON时钟
 LPC_SYSCON->SYSPLLCLKSEL = 0x00000001;  //PLL输入选择外部晶体振荡
 LPC_SYSCON->SYSPLLCLKUEN = 0x00;
 LPC_SYSCON->SYSPLLCLKUEN = 0x01;  //先写0后写1更新时钟源
 while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); //等待更新完成
 LPC_SYSCON->SYSPLLCTRL = 0x00000041;  //M=2、P=4,倍频后的时钟为24MHz
 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时钟为24MHz

在上述配置中,系统外部时钟晶振为12MHz,则在该函数执行完后,LPC824时钟就会被设置为主时钟24MHz,AHB时钟24MHz。另外,由于在默认状态下,LPC824的PIO0_8和PIO0_9两个引脚是GPIO功能,所以要连接外部晶振先要把它们配置为XTALIN、XTALOUT引脚,否则芯片不能正常工作。

上述时钟配置程序是最基本的,也是必须的,因此在任何程序开始前,都应该先调用该时钟配置函数,以对LPC824进行基本的时钟配置,为后续程序提供保障。另外,系统的主时钟也可以由内部RC时钟或看门狗时钟来充当,这将会在后面再讨论。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    基于51单片机的多功能电子钟万年历仿真设计;仿真图proteus7.8及以上 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:S0053 1.主要功能: 基于51单片机的日期时间闹钟秒表倒计时多功能电子钟......
    基于 STM32 设计的指针式电子钟与日历;1. 项目简介 这是基于 STM32 设计的一个指针式电子钟+万年历小项目,采用 3.5 寸的 LCD 屏显示时钟,日历、温度、天气,支持......
    红外遥控多功能电子钟设计方案;  本方案以AT89C51单片机为核心,软件部分采用C语言模块化设计,具有显示年、月、日、时、分、秒和温度以及闹钟和整点报时的功能,并且可通过家电通用的红外遥控器进行基本时间的调整和闹钟......
    基于STM32设计的指针式电子钟与日历;1. 项目简介 这是基于STM32设计的一个指针式电子钟+万年历小项目,采用3.5寸的LCD屏显示时钟,日历、温度、天气,支持触摸屏调整设置时间,设置闹钟......
    指针式电子钟与万年历设计方案;1. 项目简介 这是基于STM32设计的一个指针式电子钟+万年历小项目,采用3.5寸的LCD屏显示时钟,日历、温度、天气,支持触摸屏调整设置时间,设置闹钟,查看......
    结束语   系统利用VRS51L3074作为控制核心,外加专用的时钟芯片DSl2887的应用,实现时间、日历及闹钟信息显示功能。该电子钟操作方便,通过键盘和汉显液晶提示可方便地校对时钟和对闹钟进行设置。 ......
    STM32电子钟万年历时钟闹钟LCD1602仿真设计;仿真:protues 8.9 程序编译器:keil 5 编程语言:C语言 编号C0003 题目要求: 1.具有显示年、月、日、时、分、秒功能......
    STM32CubeMX之RTC电子钟;1.简介 实时时钟是一个独立的定时器。 RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改......
    基于51单片机的电子钟闹钟温度显示设计;仿真图proteus7.8及以上 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:S0057 1.主要功能: 基于51单片机AT89C51......
    全世界150多台原子钟共同守时并加权平均后的结果。各种电力系统、通信系统都离不开高精度的原子钟。 然而,由于体积大、功耗高、价格贵,原子钟未能真正进入普通电子类消费市场。 “芯片原子钟......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>