一、时钟系统基础

1.1 基本概念

  • 时钟(clock):在电子系统中是一个产生稳定、周期性振荡信号的电路或组件。这个信号像节拍器或心跳一样,为数字电路中的各种操作提供同步时序基准。
  • 定时器(EPIT GPT):是一个通过对已知频率的时钟信号进行计数,来实现定时、延时或事件计数功能的硬件模块或软件机制。
  • 实时时钟(RTC, real time clock):是微处理器中的一个功能模块,用于在系统主电源关闭的情况下,继续提供精确的日历和时间信息。

1.2 时钟系统核心组件

1.2.1 时钟源

时钟源是整个时钟系统的起点,提供稳定的原始时钟信号。

  • 晶体振荡器:将石英晶体切割成音叉,施加电压产生稳定震荡
  • 通常使用 8MHz 或 24MHz 的晶振作为基础时钟源

1.2.2 时钟树关键组件

ARM架构的时钟系统由多个关键组件构成,形成一个复杂的时钟树:

组件 作用 示例代码
PLL(锁相环) 倍频,将低频时钟提升到更高频率 CCM_ANALOG->PLL_ARM
Prescale(分频器) 分频,将高频时钟降低到所需频率 CCM->CACRR
PFD(相位分数分频器) 输出频率可升可降,提供更灵活的频率选择 CCM_ANALOG->PFD_528
MUX(多路选择器) 选择不同的时钟源 CCM->CBCMRCCM->CSCMR1
CG门(Clock Gating 控制时钟门控,节省功耗 CCM->CCGR0-CCM->CCGR6

二、时钟系统代码实现

2.1 关键时钟计算

  • ARM 内核时钟:通过PLL倍频提升到高频率。

        PLL1 倍频系数 88(24MHz×88=2112MHz)→ 二分频 → 1056MHz(可通过 CACRR 寄存器调整分频系数);

  • AHB 总线时钟:系统总线时钟,用于处理器和外设。

        PLL2 输出 528MHz → 4 分频 → 132MHz(CBCDR 寄存器的 AHB_PODF 配置);

  • IPG 总线时钟:外设接口时钟,用于GPIO、UART等外设。

        AHB 时钟 132MHz → 2 分频 → 66MHz(CBCDR 寄存器的 IPG_PODF 配置);

  • PERCLK时钟:外设时钟,用于定时器、ADC等。

        AHB 时钟 132MHz → 2 分频 → 66MHz(CSCMR1 寄存器的 PERCLK_PODF 配置)。

2.2 时钟初始化

void clock_init(void)
{
  // ARM内核时钟切换(避免配置PLL时内核故障)
  CCM->CCSR &= ~(1 << 8);  // 选择osc_clk作为step_clk(24MHz)
  CCM->CCSR |= (1 << 2);   // 让ARM暂时工作在step_clk(24MHz)
  
  // 配置ARM内核分频器(CACRR)
  CCM->CACRR &= ~(7 << 0);
  CCM->CACRR |= (1 << 0);  // 二分频(后续PLL1输出1056MHz,分频后528MHz)
  
  // 配置PLL1(ARM PLL)为1056MHz
  unsigned int t = CCM_ANALOG->PLL_ARM;
  t &= ~(3 << 4);          // 清除原有倍频系数
  t |= (1 << 13);          // 使能PLL
  t &= ~(0x7F << 0);
  t |= (88 << 0);          // 倍频系数88(24×88=2112MHz,二分频后1056MHz)
  CCM_ANALOG->PLL_ARM = t;
  CCM->CCSR &= ~(1 << 2);  // 切换回PLL1输出(pll1_main_clk)
  
  // 配置PLL2(528MHz)的PFD分频器
  t = CCM_ANALOG->PFD_528;
  t &= ~((0x3F << 0) | (0x3F << 8) | (0x3F << 16) | (0x3F << 24));
  // PFD0=27→352M,PFD1=16→594M,PFD2=24→396M,PFD3=32→297M
  t |= ((27 << 0) | (16 << 8) | (24 << 16) | (32 << 24));
  CCM_ANALOG->PFD_528 = t;
  
  // 配置PLL3(480MHz)的PFD分频器
  t = CCM_ANALOG->PFD_480;
  t &= ~((0x3F << 0) | (0x3F << 8) | (0x3F << 16) | (0x3F << 24));
  t |= ((27 << 0) | (16 << 8) | (24 << 16) | (32 << 24));
  CCM_ANALOG->PFD_480 = t;
  
  // 配置AHB_CLK_ROOT(132M)
  t = CCM->CBCMR;
  t &= ~(3 << 18);
  t |= (1 << 18);          // 选择PLL2_PFD2(396M)作为输入
  CCM->CBCMR = t;
  t = CCM->CBCDR;
  t &= ~(1 << 25);
  t &= ~(7 << 10);
  t |= (2 << 10);          // AHB分频系数3(396M/3=132M)
  CCM->CBCDR = t;
  
  // 配置IPG_CLK_ROOT(66M)
  t &= ~(3 << 8);
  t |= (1 << 8);           // IPG分频系数2(132M/2=66M)
  CCM->CBCDR = t;
  
  // 配置PERCLK_CLK_ROOT(66M)
  t = CCM->CSCMR1;
  t &= ~(1 << 6);          // 选择IPG_CLK_ROOT作为输入
  t &= ~(0x3F << 0);       // 不分频
  CCM->CSCMR1 = t;
  
  // 使能所有外设时钟门控(CG)
  clock_cg_init();
}

时钟配置关键注意事项:

  • 时钟切换顺序:配置 PLL1 时,必须先将 ARM 内核切换到 24MHz 的 step_clk,避免倍频过程中内核因时钟突变而故障;
  • 分频系数匹配:外设时钟必须与器件手册要求一致(如 USB 需 480MHz,以太网需特定频率),否则会导致外设工作异常;
  • 时钟门控使能:clock_cg_init() 函数将所有 CCGR 寄存器置为 0xFFFFFFFF,即开启所有外设时钟,实际项目中可按需关闭未使用外设的时钟以降低功耗。

三、定时器模块详解

3.1 EPIT 定时器

Enhanced Periodic Interrupt Timer —— 增强型周期中断定时器

应用场景:周期性任务,如 1 秒翻转一次 LED。

工作原理:

  • 定时器根据配置的时钟源进行计数。
  • 当计数达到 LR  (Load Register) 设定的值时,产生中断,并将计数器自动重置为 LR 值。

实验:1秒中断翻转 LED
使用 PERCLK_CLK_ROOT (66MHz) 作为时钟源。

  • 目标频率:1Hz(即每1秒一次)。
  • 1秒中断的计算:1000 * 1000 = 1MHz(1MHz时钟,100万计数=1秒)
  • 代码实现:
void epit1_init(void)
{
    unsigned int t;
    t = EPIT1->CR;
    t &= ~(3 << 24);    // 清除时钟源选择
    t |= (1 << 24);     // 选择PERCLK_CLK_ROOT(66M)作为时钟源
    t |= (1 << 17);     // 覆盖计数器值
    t &= ~(0xFFF << 4); // 清除预分频值
    t |= (65 << 4);     // 分频系数66(66M/66=1MHz)
    t |= (1 << 3);      // 计数器达到零时,从模数寄存器重新加载(置位-遗忘模式)
    t |= (1 << 2);      // 启用中断
    t |= (1 << 1);      // 从加载值开始计数
    EPIT1->CR = t;
    
    EPIT1->LR = 1000 * 1000;  // 载入值 = 1MHz时钟,1秒
    EPIT1->CMPR = 0;          // 比较寄存器
    EPIT1->CNR = 1000 * 1000; // 当前计数值
    
    // 中断配置
    GIC_EnableIRQ(EPIT1_IRQn);
    GIC_SetPriority(EPIT1_IRQn, 0);
    system_interrupt_register(EPIT1_IRQn, epit_irq_handler);
    
    EPIT1->CR |= (1 << 0); // 使能定时器
}
 
// 中断服务函数:1s翻转LED和蜂鸣器
void epit_irq_handler(void)
{
  if ((EPIT1->SR & (1 << 0)) != 0)
  {
    led_nor();
    beep_nor();
    EPIT1->SR |= (1 << 0); // 清除中断标志
  }
}

3.2 GPT定时器

General Purpose Timer —— 通用目的定时器

应用场景:高精度延时函数。

工作原理:GPT 支持自由运行模式、输入捕获和比较输出。我们利用其自由运行模式读取当前计数值来实现软件延时。

实验:精准延时
通过读取 GPT1->CNT 寄存器,对比当前值与上一次的值,累加时间差,直到达到所需的微秒数。

  • 代码实现:
    void gpt1_init(void)
    {
        // 复位定时器
        reset_fun();
        
        unsigned int t;
        t = GPT1->CR;
        t &= ~(7 << 26);  // 输出断开
        t &= ~(3 << 18);  // 捕获已禁用
        t |= (1 << 9);    // 自由运行模式
        t &= ~(7 << 6);   // 清除时钟源选择
        t |= (1 << 6);    // 选择PERCLK_CLK_ROOT(66M)作为时钟源
        t &= ~(1 << 1);   // 失能定时器后保留原来的值
        GPT1->CR = t;
        
        GPT1->PR &= ~(0xFFF << 0); // 清除预分频值
        GPT1->PR |= (65 << 0);     // 分频系数66(66M/66=1MHz)
        GPT1->CNT = 0;             // 清零计数器
        GPT1->CR |= (1 << 0);      // 使能定时器
    }
     
    // 微秒级延时函数
    void delay_us(unsigned int us)  
    {  
        unsigned int count = 0;  
        unsigned int old_count = 0, new_count = 0;  
        
        old_count = GPT1->CNT; // 记录起始时刻  
        while (1)  
        {  
            new_count = GPT1->CNT;  
          
            // 计算溢出情况(例如从0xFFFFFFFF变到0)  
            if (new_count != old_count)  
            {  
                if (new_count > old_count)  
                {  
                    count += new_count - old_count;  
                }  
                else  
                {  
                    count += 0xFFFFFFFF - old_count + new_count;  
                }  
            }  
          
            if (count >= us)  
            {  
                return;  
            }  
            old_count = new_count;  
        }  
    }  

    四、总结

         ARM架构的时钟系统和定时器模块是嵌入式系统设计的核心组件。理解时钟树的结构和工作原理,对于实现精确的定时控制、优化系统功耗和性能至关重要。

  • 时钟系统:通过PLL、分频器和多路选择器构建复杂的时钟树,为系统提供精确的时序基准
  • 定时器:EPIT提供精确的周期中断,GPT提供灵活的延时功能,两者在嵌入式系统中广泛应用
  • 配置实践:通过寄存器配置,实现时钟频率的精确控制和定时器的精准工作

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐