IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【嵌入式系统设计】LPC1100系列微控制器基础——时钟系统 -> 正文阅读

[嵌入式]【嵌入式系统设计】LPC1100系列微控制器基础——时钟系统

? ? ? 🔥《嵌入式系统开发》系列专栏主要以LPC1100系列微控制器为硬件平台,详细介绍Cortex—-M0微控制器的原理与开发技术,基于keil仿真软件平台设计最小应用系统板和具有在板仿真器的口袋开发板以及相关例程。

? ? ? 🔥本文已收录于嵌入式系统开发系列专栏:嵌入式系统开发 欢迎订阅,持续更新。

【嵌入式系统设计】LPC1100系列微控制器基础——时钟系统

文章目录

LPC1100时钟产生单元

工作机制

系统控制模块SCB寄存器(与系统时钟有关)

振荡器选择

?内部RC振荡器

主振荡器

看门狗振荡器

看门狗振荡器控制寄存器WDTOSCCTRL

系统振荡器控制寄存器SYSOSCCTRL

?PLL工作原理与使用

PLL频率计算中的公式

PLL初始化步骤

系统初始化函数void Systemlnit (void)

void SystemCoreClockU pdate (void)函数


LPC1100时钟产生单元

工作机制

?LPC1100含有3个独立的振荡器:

系统振荡器:12MHZ

内部RC振荡器(IRC):12MHZ(与外部晶振相关)

看门狗振荡器(MDT):0.2MHZ

●复位后,LPC1100系列微控制器自动选择内部RC振荡器(12MHz) 作为系统的时钟源,这使得系统能在没有外部晶振的情况下运行。
●一旦进入ISP模式,Boot Block程序使用内部RC振荡器作为PLL的输入时钟源,并产生14.748MHz系统时钟。(产生误差较小的波特率)
●系统AHB时钟控制寄存器SYSAHBCLKCTRL控制着各种外设和存储器的系统时钟。
●UART和SSP0/1都有单独的时钟分频器,可以从主时钟分频产生外设所需的时钟频率。
●主时钟以及从IRC振荡器、系统振荡器和看门狗振荡器输出的时钟均可以直接在GLKOUT弓|脚上观察到。

系统控制模块SCB寄存器(与系统时钟有关)

振荡器选择

●用户可以通过软件方式修改时钟源选择寄存器,从而选择3种振荡器中的一种作为系统主时钟源。但需要注意,在切换前必须保证即将使用的时钟源已经可用。
●所有振荡器在用作CPU时钟源时,可以通过PLL获得较高的Fcclk值(必须小于或等于50MHz)。

?内部RC振荡器

内部RC振荡器(IRC) 可用作看i门狗定时器的时钟源,也可以用作系统PLL和CPU的时钟源。
●IRC的标称频率为12MHz (精度为+1%),在一些特殊的应用场合(例如USB接口通信等)则需要使用精度更高的外部晶体振荡器作为系统时钟源。
●在上电或任何片上复位时,LPC1100系列微控制器使用IRC作为时钟源。此后,用户可通过编程切换到另一种可用的时钟源。

●在ISP模式,Boot Block将用IRC作为系统时钟源设置PLL,并产生14.748MHz系统时钟。

主振荡器

●主振荡器(外部晶体振荡器)可作为CPU的时钟源(不管是否使用PLL)。主振荡器工作在10MHz ~ 25MHz下,用户可通过PLL来提高CPU的工作频率。主振荡器的输出称为

OSC_ CLK,可被选择用作PLL入时钟PLLCLKIN。
●Cortex-M0处理器的工作频率称为CCLK,在PLL无效或还未连接时,PLLCLKIN和CCLK的值是相同的。

看门狗振荡器

●看门狗振荡器(WDT)可用作看i门狗定时器的时钟源,也可以用作CPU的时钟源。
●由于看门狗振荡器的频率为500KHz ~ 3.4MHz (精度为士25%) ,所以在一.些特殊的应用场合(例如使用串口)则需要使用IRC振荡器或精度更高的外部晶体振荡器作为系统时钟源。

看门狗振荡器控制寄存器WDTOSCCTRL

看门狗振荡器控制寄存器用于配置看门狗振荡器。
●利用位FREQSEL对Fclkana时钟信号进行调节,并可以利用位DIVSEL对Fclkana时钟信号进行分频。
●看门狗振荡器的输出时钟频率的计算公式如下:
wdt_ OSC_ cIk = Fclkana/ (2x(1+DIVSEL)
●当看门狗振荡控制器复位时,看门狗振荡器的输出时钟频率为:
wdt_ OSC_ clk = 1.6MHz/2x (1+0) =800kHz

系统振荡器控制寄存器SYSOSCCTRL

系统振荡器控制寄存器用于配置系统振荡器的频率范围。

?PLL工作原理与使用

LPC1100系列微型控制器利用PLL来为内核以及外设提供时钟信号

●?PLL时钟源的选择在SYSPLLCLKSEL寄存器中设置,PLL将输入时钟升频,然后再分频以提供CPU及芯片外设所使用的实际时钟。PLL可产生的时钟频率最可达50MHz,这也是CPU的最高工作频率。
●PLL接受的输入时钟频率范围为10MHz~25MHz,输入时钟直接馈送到"相位频率检测”部件,该部件会比较两个输出信号的相位和频率,并根据误差输出不同的电流值来控制CCO的振荡频率。
●通常CCO的输出频率是有限的,超出这个范围则无法输出预期的时钟信号。LPC1100系列微控制器内部的CCO可工作在156MHz ~ 320MHz。

PLL频率计算中的公式

●FCLKouτ= M x FCLKIN = FCCO / (2xP)
●为了选择合适的M和P值,推荐如下步骤:
●指定输入时钟频率FCLKIN ;
●计算M值以获得所需的输出频率FCLKOUT1,M=FCLKOUT/?FcLKIN;
●找出一个值使得Fcco=2xPx FCLKOUT;
●检查所有的频率和分频器值设置,是否符合系统PLL控制寄存器(SYSPLLCTRL)位功能描述内的限定。
●在PLL的输入时钟频率范围为10MHz~25MHz下,允许M值的范围为1~32,这是支持主振荡器和IRC操作的整个M值的范围。

例如:输出频率48MHZ,输入频率12MHZ

此时M为4;

FCCO可为192MHZ;

此时P为2;

PLL初始化步骤

●如果选择主振荡器作为PLL的输入时钟源,则在PDRUNCFG中对主振荡器先.上电;
●在系统PLL时钟源选择寄存器中选择作为PLL输入的时钟源,主振荡器或IRC振荡器;
●写系统PLL时钟源更新使能寄存器,使系统PLL时钟源选择有效;
●在系统PLL控制寄存器中写计算好的M和P值;
●在PDRUNCFG中对系统PLL上电,并等待PLL信号锁定;
●在主时钟源选择寄存器中选择PLL时钟作为系统的时钟;
●写主时钟源选择更新使能寄存器,使主时钟源选择系统PLL时钟输出有效。

●系统PLL控制寄存器连接并使能系统PLL、配置PLL倍频器和分频值。

系统初始化函数void Systemlnit (void)

●CMSIS在文件system_ LPC11xx. c中定义了LPC1100的系统初始化函数void Systemlnit (void), 在函数中对系统主时钟进行了配置,启动文件startup_ LPC11xx. s在复位后直接调用了该函数完成了系统初始化,系统时钟被设置为48MHz,然后跳转到main函数。

void SystemInit (void) {
  volatile uint32_t i;

#if (CLOCK_SETUP)                                 /* Clock Setup              */

#if ((SYSPLLCLKSEL_Val & 0x03) == 1)
  LPC_SYSCON->PDRUNCFG     &= ~(1 << 5);          /* Power-up System Osc      */
  LPC_SYSCON->SYSOSCCTRL    = SYSOSCCTRL_Val;
  for (i = 0; i < 200; i++) __NOP();
#endif

  LPC_SYSCON->SYSPLLCLKSEL  = SYSPLLCLKSEL_Val;   /* Select PLL Input         */
  LPC_SYSCON->SYSPLLCLKUEN  = 0x01;               /* Update Clock Source      */
  LPC_SYSCON->SYSPLLCLKUEN  = 0x00;               /* Toggle Update Register   */
  LPC_SYSCON->SYSPLLCLKUEN  = 0x01;
  while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01));     /* Wait Until Updated       */
#if ((MAINCLKSEL_Val & 0x03) == 3)                /* Main Clock is PLL Out    */
  LPC_SYSCON->SYSPLLCTRL    = SYSPLLCTRL_Val;
  LPC_SYSCON->PDRUNCFG     &= ~(1 << 7);          /* Power-up SYSPLL          */
  while (!(LPC_SYSCON->SYSPLLSTAT & 0x01));	      /* Wait Until PLL Locked    */
#endif

#if (((MAINCLKSEL_Val & 0x03) == 2) )
  LPC_SYSCON->WDTOSCCTRL    = WDTOSCCTRL_Val;
  LPC_SYSCON->PDRUNCFG     &= ~(1 << 6);          /* Power-up WDT Clock       */
  for (i = 0; i < 200; i++) __NOP();
#endif

  LPC_SYSCON->MAINCLKSEL    = MAINCLKSEL_Val;     /* Select PLL Clock Output  */
  LPC_SYSCON->MAINCLKUEN    = 0x01;               /* Update MCLK Clock Source */
  LPC_SYSCON->MAINCLKUEN    = 0x00;               /* Toggle Update Register   */
  LPC_SYSCON->MAINCLKUEN    = 0x01;
  while (!(LPC_SYSCON->MAINCLKUEN & 0x01));       /* Wait Until Updated       */

  LPC_SYSCON->SYSAHBCLKDIV  = SYSAHBCLKDIV_Val;
#endif

}

void SystemCoreClockU pdate (void)函数

●CMSIS在文件system_ LPC11xx.c中定义了一 -个全局变量SystemCoreClock和一-个函数void SystemCoreClockUpdate(void),用来获得当前处理器的工作频率,用户程序可以直接使用该变量。
●用户程序每次在时钟配置完成之后,需要调用这个函数来更新SystemCoreClock变量"(CCLK),否则在使用.SystemCoreClock变量时可能会导致错误。
●uint32_ t SystemCoreClock =__ SYSTEM_ CLOCK;
●/*!< System Clock Frequency (Core Clock)*/

void SystemCoreClockUpdate (void)            /* Get Core Clock Frequency      */
{
  uint32_t wdt_osc = 0;

  /* Determine clock frequency according to clock register values             */
  switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
    case 0:  wdt_osc =       0; break;
    case 1:  wdt_osc =  500000; break;
    case 2:  wdt_osc =  800000; break;
    case 3:  wdt_osc = 1100000; break;
    case 4:  wdt_osc = 1400000; break;
    case 5:  wdt_osc = 1600000; break;
    case 6:  wdt_osc = 1800000; break;
    case 7:  wdt_osc = 2000000; break;
    case 8:  wdt_osc = 2200000; break;
    case 9:  wdt_osc = 2400000; break;
    case 10: wdt_osc = 2600000; break;
    case 11: wdt_osc = 2700000; break;
    case 12: wdt_osc = 2900000; break;
    case 13: wdt_osc = 3100000; break;
    case 14: wdt_osc = 3200000; break;
    case 15: wdt_osc = 3400000; break;
  }
  wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
 
  switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
    case 0:                             /* Internal RC oscillator             */
      SystemCoreClock = __IRC_OSC_CLK;
      break;
    case 1:                             /* Input Clock to System PLL          */
      switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
          case 0:                       /* Internal RC oscillator             */
            SystemCoreClock = __IRC_OSC_CLK;
            break;
          case 1:                       /* System oscillator                  */
            SystemCoreClock = __SYS_OSC_CLK;
            break;
          case 2:                       /* Reserved                           */
          case 3:                       /* Reserved                           */
            SystemCoreClock = 0;
            break;
      }
      break;
    case 2:                             /* WDT Oscillator                     */
      SystemCoreClock = wdt_osc;
      break;
    case 3:                             /* System PLL Clock Out               */
      switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
          case 0:                       /* Internal RC oscillator             */
            if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
              SystemCoreClock = __IRC_OSC_CLK;
            } else {
              SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
            }
            break;
          case 1:                       /* System oscillator                  */
            if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
              SystemCoreClock = __SYS_OSC_CLK;
            } else {
              SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
            }
            break;
          case 2:                       /* Reserved                           */
          case 3:                       /* Reserved                           */
            SystemCoreClock = 0;
            break;
      }
      break;
  }

  SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;  

}

LPC1100时钟产生单元(初始化后)

?小问题:如何降低系统工作频率为24MHz?

笔者认为:

1.选择合适的M和P值

2.重新调用这个函数来更新SystemCoreClock变量

? ? ? 🔥《嵌入式系统开发》系列专栏主要以LPC1100系列微控制器为硬件平台,详细介绍Cortex—-M0微控制器的原理与开发技术,基于keil仿真软件平台设计最小应用系统板和具有在板仿真器的口袋开发板以及相关例程。

? ? ? 🔥本文已收录于嵌入式系统开发系列专栏:嵌入式系统开发 欢迎订阅,持续更新。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-24 21:12:15  更:2022-09-24 21:14:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:40:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码