裸机开发 时钟配置,EPIT

发布于:2025-09-15 ⋅ 阅读:(29) ⋅ 点赞:(0)

1.概念

时钟(clock):在电子系统中是一个产生稳定、周期性振荡信号的电路或组件。这个信号像节拍器或心跳一样,为数字电路中的各种操作提供同步时序基准。

PLL(phase locked loop)锁相环电路: 倍频

PFD(phase fractional Prescale)相位分数分频器: 输出频率可升可降

2.时钟配置

1.CCM

CCM 是 i.MX6U 时钟系统的 “大脑”,通过 PLL(锁相环,倍频) 和 Divider(分频器) 实现时钟信号的 “精准缩放”,核心模块包括:

  • PLL 模块(倍频核心)
    接收低频时钟源(如 24MHz XTAL),通过倍频生成高频时钟,供高性能模块使用。i.MX6U 针对不同时钟域设计了专用 PLL:

    • PLL1(ARM PLL)Cortex-A7 CPU 的专属 PLL,最高可将 24MHz 倍频至 792MHz(即 CPU 最高主频 792MHz,需配合电压调整)。
    • PLL2(System PLL):为外设域提供基础时钟,输出固定 528MHz,再通过分频供给 UART、SPI、GPT 等外设。
    • PLL3(USB PLL):专门为 USB 模块提供 480MHz 时钟(USB 2.0 高速模式需求)。
    • PLL4(Audio PLL):为音频模块(如 I2S)提供精准时钟,支持灵活配置频率。
  • Divider 模块(分频调节)
    对 PLL 输出的高频时钟进行 “降压”,适配不同模块的时钟需求(如 UART 常用 115200bps 波特率,需 8MHz 或 16MHz 时钟)。
    例:PLL2 输出 528MHz → 经分频器(÷66)得到 8MHz → 供给 UART1 模块。

  • Clock Gate(时钟门控)
    为每个模块提供独立的 “时钟开关”—— 未使用的模块可关闭时钟(如 UART2 未使用时,关闭其时钟),是 i.MX6U 低功耗设计的关键。

2.PLL模块

1.PLL1

kernal: CCM_ANALOG_PLL_ARMn

配置步骤:

  1. 先选择osc_clk,让step_clk为24MHz
  2. 再将PLL1的输出改成step_clk,让ARM暂时工作在24MHz;
  3. 配置PLL为1056MHz,注意设置倍频因子之前先把PLL之后的二分频设置好,避免ARM内核故障!!
  4. 最后改回pll1_main_clk

示例

//ARM工作时钟配置              先分频再倍频保证ARM内核正常工作
    CCM->CACRR &= ~(7 << 0);   //先清0
    CCM->CACRR |= (1 << 0);  //设置为2分频(001)

    CCM->CCSR &= ~(1 << 8);    //设置24MHz
    CCM->CCSR |= (1 << 2);     //设为另外一路(step_clk),此时 锁相环短路(pll1_main_clk)(PPL_ARM), 可安全配置PPL_ARM

    unsigned int t = CCM_ANALOG->PLL_ARM;   //此时可安全配置PPL_ARM
    t &= ~(0x7F << 0);
    t |= (88 << 0);
    t |= (1 << 13);
    t &= ~(3 << 14);
    CCM_ANALOG->PLL_ARM = t;

    CCM->CCSR &= ~(1 << 2);     //切换回PPL_ARM路

2.528PLL

它是 i.MX6U 芯片中负责为高速外设和关键功能模块提供稳定、高频时钟的核心锁相环(PLL),因输出时钟最高可配置为528MHz而得名,是整个芯片时钟树中至关重要的 “高频时钟源” 之一。

CCM_ANALOG_PFD_528n

由手册知,相关配置为

故PLL2下的PFDn需要配置的MHz如图,相关计算公式为

故对于PFD0来说为528 * 18 / 352 = 27

示例

    t = CCM_ANALOG->PFD_528;
    t &= ~((0x3F << 0) | (0x3F << 8) | (0x3F << 16) | (0x3F << 24));  //先清0
    t |= ((27 << 0) | (16 << 8) | (24 << 16) | (32 << 24));
    CCM_ANALOG->PFD_528 = t;

3.PLL3

在 i.MX6U 芯片中,PLL3(USB PLL) 是专门为 USB(通用串行总线)模块设计的锁相环(PLL),其核心作用是为 USB 控制器提供符合协议规范的高精度时钟信号

相关配置如图

示例如图

    t = CCM_ANALOG->PFD_480;
    t &= ~((0x3F << 0) | (0x3F << 8) | (0x3F << 16) | (0x3F << 24));  //先清0
    t |= ((12 << 0) | (16 << 8) | (17 << 16) | (19 << 24));
    CCM_ANALOG->PFD_480 = t;

3.时钟根配置

需配置AHB_CLK_ROOT    132MHZ

           PERCLK_CLK_ROOT  66MHz

           IPG_CLK_ROOT        66MHz

在 i.MX6U(基于 Cortex-A7 架构)的时钟树中,AHB_CLK_ROOTPERCLK_CLK_ROOT 和 IPG_CLK_ROOT 是三个核心的 “时钟根节点”,它们从上层 PLL 获取时钟信号后,通过分频或直接分配,为不同类型的外设、总线和功能模块提供时钟。三者的定位、频率来源和服务对象有明确分工,共同构成了外设时钟域的核心架构。

AHB(Advanced High-performance Bus,高级高性能总线)是芯片内部的高速数据传输总线,AHB_CLK_ROOT 是该总线的根时钟,决定了高速外设和内存接口的数据传输速率。

IPG(Internal Peripheral Bus,内部外设总线)是 AHB 总线的 “子总线”,主要连接中速外设,IPG_CLK_ROOT 是该总线的根时钟,也是多数通用外设的基础时钟源。

PERCLK(Peripheral Clock,外设时钟)是 IPG 总线的 “低速分支”,PERCLK_CLK_ROOT 专为对时钟频率要求较低的外设设计,是低速外设的统一时钟源。

示例

    //AHB_clk_root配置
    CCM->CBCMR &= ~(3 << 18);     //先清0
    CCM->CBCMR |= (1 << 18);      //选择 pll2的pfd2

    t = CCM->CBCDR;
    t &= ~(1 << 25);     //选通pll2的门
    t &= ~(7 << 10);     //清0
    t |= (2 << 10);      //设为010三分频

    //IPG_CLK_ROOT配置
    t &= ~(3 << 8);      //清0
    t |= (1 << 8);      //设为001二分频     IPG_CLK_ROOT
    CCM->CBCDR = t;

    //PRECLK-CLK_ROOT配置
    t = CCM->CSCMR1;
    t &= ~(1 << 6);       //选通所要选择的路
    t &= ~(0x3F << 0);    //设为1分频       PRECLK-CLK_ROOT
    CCM->CSCMR1 = t;

3.EPIT

1.工作模式

EPIT 支持两种经典工作模式,核心差异在于计数到 0 后的行为:

1. 重装载模式(Reload Mode)
  • 工作逻辑:计数器从 LR(重装载寄存器)的值开始向下计数,当计数到 0 时:
    1. 触发 “计数结束中断”;
    2. 自动将 LR 的值重新装
    3. 载到计数器,开始新一轮计数(无需软件干预)。
  • 核心特点:中断间隔严格固定(周期 = LR 值 × 计数周期),无累积误差,适合周期性任务(如 1ms 一次的系统节拍)。
  • 示例:若 LR=1000,计数周期 = 1μs,则每 1000μs(1ms)触发一次中断,循环往复。
2. 自由运行模式(Free-Run Mode)
  • 工作逻辑:计数器从 LR 的值开始向下计数,当计数到 0 时:
    1. 触发 “计数结束中断”;
    2. 计数器停止计数(保持 0 值),需通过软件重新写入 LR 值才能再次启动。
  • 核心特点:仅触发一次中断,适合单次定时(如延时 10ms 后执行某个初始化操作)。
  • 示例:若 LR=10000,计数周期 = 1μs,则 10ms 后触发一次中断,之后计数器停止。

2.相关配置

示例

void epit1_init(void)
{
    unsigned int t;
    
    t = EPIT1->CR;

    t &= ~(3 << 24);    //先清0,再写1
    t |= (1 << 24);     //设置时钟源为外设时钟irq_clk_root
    t |= (1 << 17);
    t &= ~(0xFFF << 4);  //清0
    t |= (65 << 4);      //分频66倍(65+1)后即为1MHz
    t |= (1 << 3);       //set-forget模式
    t |= (1 << 2);       //比较中断启用
    t |= (1 << 1);   

    EPIT1->CR = t;

    EPIT1->LR = 1000000;
    EPIT1->CMPR = 0;
    EPIT1->CNR = 1000000;

    //注册中断处理函数
    system_interrupt_register(EPIT1_IRQn, epit1_irq_handler);
    //GIC中断使能
    GIC_EnableIRQ(EPIT1_IRQn);
    //GIC中断优先级设置
    GIC_SetPriority(EPIT1_IRQn, 0);

    //enable
    EPIT1->CR |= (1 << 0);   //EPIT启用,注意最后再启用
}