【嵌入式系统设计】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仿真软件平台设计最小应用系统板和具有在板仿真器的口袋开发板以及相关例程。

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
11AA010/11LC010 11AA080/11LC080 11AA020/11LC020 11AA160/11LC160 11AA040/11LC040 11AA161/11LC161 特性: • 单I/O UNI/O®串行接口总线 • 低功耗CMOS技术: - 1 mA工作电流 (典型值) - 1 µA待机电流 (最大值)(工业级温度) • 128 x 8位至2,048 x 8位构成 • 用于抑制噪声的施密特触发器输入 • 用于消除地弹效应的输出斜率控制 • 最大比特率为100 kbps——等同于时钟频率为 100 kHz • 自定时写周期 (包括自动擦除) • 最大16字节的页写缓冲区 • 新增控制功能的STATUS (状态)寄存器: - 写使能锁存器位 - 写进行位 • 块写保护: - 无保护,以及保护1/4、 1/2或全阵列 • 内置写保护: - 上电/断电数据保护电路 - 写使能锁存器 • 高可靠性: - 耐用性:可耐受100万次擦写 - 数据保持: > 200年 - ESD 保护: > 4,000V • 3引脚SOT-23和TO-92封装 • 4引脚芯片级封装 • 8引脚PDIP、 SOIC、 MSOP和TDFN封装 • 符合无铅和RoHS标准 • 工作温度范围: 引脚功能表 说明: Microchip Technology Inc. 的 11AAXXX/11LCXXX (11XX*)器件是容量从1 Kb至16 Kb的串行EEPROM 器件系列。器件由x8位的存储块组成,支持拥有专利**的 单I/O UNI/O®串行总线。通过使用曼彻斯特编码技术, 时钟和数据组合成一个单串行比特流(SCIO),接收器 从其中提取时钟信号用于正确解码时序和每个位的值。 低电压设计允许工作在最低1.8V (针对11AAXXX器 件),同时待机电流和工作电流分别仅为1 uA和1 mA。 11XX系列可使用8引脚PDIP和SOIC的标准封装,以及 3引脚SOT-23、 3引脚TO-92、 4引脚芯片级、 8引脚 TDFN和8引脚MSOP的高级封装。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Karry D

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值