当前位置: 首页 > news >正文

基于IMX6ULL的时钟,定时器(EPIT,GPT)

(1)时钟:

1.PLL(锁相环,Phase - Locked Loop):倍频

  • 定义:PLL 是一种反馈控制系统,它能够自动跟踪输入信号的频率和相位,使输出信号的频率和相位与输入信号保持同步 。它主要由鉴相器(PD,Phase Detector)、环路滤波器(LF,Loop Filter)和压控振荡器(VCO,Voltage - Controlled Oscillator)三个基本部件组成。
  • 作用:在 IMX6ULL 等芯片中,PLL 的主要作用是产生稳定的、高精度的时钟信号。它可以将一个较低频率的参考时钟信号,通过倍频等操作,产生满足芯片内部不同模块(如 CPU 内核、外设接口等)工作需求的多种频率的时钟信号。例如,ARM PLL 可以为 ARM 内核提供合适的工作频率 。

2.Prescaler(预分频器):分频

  • 定义:Prescaler 是一种数字电路模块,它可以对输入的时钟信号进行分频处理,即将输入时钟信号的频率降低为原来的几分之一 。比如一个 2 分频的预分频器,会使输出时钟信号频率变为输入时钟信号频率的一半。
  • 作用:在 IMX6ULL 芯片中,预分频器主要用于调整时钟信号的频率,使其满足特定模块的工作需求。通过对 PLL 输出的时钟信号进行分频,可以得到适合不同外设工作的时钟频率,同时也有助于降低功耗,因为一些外设不需要太高的时钟频率。

3.PFD(相位频率检测器,Phase - Frequency Detector):既可以用分频也可以倍频

  • 定义:PFD 是 PLL 中的一个关键部件,它主要用于比较输入信号和反馈信号的相位和频率,并输出一个反映两者差异的信号 。
  • 作用:在 PLL 环路中,PFD 的输出信号会被送到环路滤波器进行处理,然后再去控制压控振荡器(VCO)的输出频率和相位。通过不断比较和调整,PLL 可以使输出信号与输入信号保持同频同相。在 IMX6ULL 中,PFD 与 PLL 配合,实现稳定的时钟信号生成和调整。

4.IMX6ULL 中的 PLL 和 PFD 数量

①PLL 数量IMX6ULL 通常有7个 PLL,常见的包括

  1. ARM PLL:这是ARM核心复合体的PLL时钟。
  2. System PLLor 528_PLL:从 XTALOSC 产生 24 MHz 的参考频率,输出 528 MHz 的频率
  3. USB1 PLLor 480_PLL:固定480MHz的频率
  4. Audio PLL:
  5. Video PLL :
  6. ENET_PLL:
  7. USB2_PLL:
  • PFD 数量:IMX6ULL 中存在多个 PFD,例如与 528 PLL 和 480 PLL 相关的 PFD,它们与对应的 PLL 协同工作,为系统提供多种频率选择。具体数量会根据芯片手册的定义和不同的配置模式有所差异,但一般会有多个 PFD 来满足不同的时钟生成和调整需求。

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

配置ARM PLL:

1. 配置 ARM 工作频率(主频相关寄存器 CCM->CCSR

  • CCM->CCSR &= ~(1<<8);
    • 对 CCM 模块的 CCSR 寄存器的第 8 位 清零CCSR(Clock Control Switch Register)是时钟控制切换寄存器,该操作通常用于关闭某个与 ARM 主频相关的默认时钟路径或功能。
  • CCM->CCSR |= (1<<2);
    • 对 CCM->CCSR 的第 2 位 置 1。这一步是选择 ARM 内核的时钟源(比如切换到某个 PLL 输出的时钟),为后续设置 ARM 主频做准备。
// 配置ARM内核时钟源及PLL参数,设置ARM工作频率
// 参考i.MX6ULL芯片手册中CCM(时钟控制模块)和PLL相关寄存器定义// 1. 配置时钟控制切换寄存器(CCSR),准备切换ARM时钟源
// CCSR寄存器:用于选择ARM内核时钟源和控制时钟路径
// 第8位:通常用于关闭默认时钟源或使能时钟切换准备
CCM->CCSR &= ~(1<<8);    // 清除CCSR第8位,关闭默认时钟路径或相关功能// 第2位:ARM_PODF(ARM分频器)时钟源选择位
// 置1时,通常选择PLL_ARM作为ARM时钟源的前级时钟
CCM->CCSR |= (1<<2);     // 设置CCSR第2位,选择PLL_ARM作为ARM时钟源// 2. 配置ARM分频寄存器(CACRR),设置ARM内核最终分频系数
// CACRR寄存器:控制ARM内核时钟的分频比例(ARM_PODF)
// 低3位(bit0~bit2):表示分频系数,公式为 分频值 = (bit值 + 1)
CCM->CACRR &= ~(7<<0);   // 清除低3位,清除原有分频设置
CCM->CACRR |= (1<<0);    // 设置低3位为0b001,即分频系数为2(1+1)// 3. 配置ARM锁相环(PLL_ARM),生成高频基准时钟
unsigned int t;           // 临时变量,用于寄存器值的修改(避免直接操作寄存器覆盖其他位)// 读取当前PLL_ARM寄存器值
t = CCM_ANALOG->PLL_ARM;// PLL_ARM寄存器bit14~15:PLL工作模式配置位
// 清零这两位,通常用于禁用PLL旁路模式,启用正常锁相环模式
t &= ~(3<<14);            // 清除bit14~15,配置PLL为正常工作模式// PLL_ARM寄存器bit13:PLL使能/控制位
// 置1时,通常用于使能PLL的倍频功能或锁定控制
t |= (1<<13);             // 设置bit13,使能PLL_ARM的倍频功能// PLL_ARM寄存器bit0~bit6:倍频系数配置位(NDIV)
// 清零这7位,清除原有倍频设置
t &= ~(0x7F<<0);          // 清除bit0~bit6,准备设置新的倍频系数// 设置倍频系数为88(bit0~bit6赋值88)
// 公式:PLL输出频率 = 参考时钟频率 * 倍频系数
// 假设参考时钟为24MHz,则此时PLL输出为24MHz * 88 = 2112MHz
t |= (88<<0);             // 设置bit0~bit6为88,配置PLL_ARM倍频系数// 将修改后的值写回PLL_ARM寄存器,完成PLL配置
CCM_ANALOG->PLL_ARM = t;// 4. 完成时钟源切换,使新配置生效
// 清除CCSR第2位,确认时钟源切换完成,ARM内核开始使用PLL_ARM经过分频后的时钟
CCM->CCSR &= ~(1<<2);     // 确认切换,ARM时钟源正式切换为PLL_ARM分频后输出// 最终ARM内核频率计算:
// PLL_ARM输出(2112MHz) ÷ CACRR分频系数(2) = 1056MHz

时钟树:

(2)定时:

1.EPIT(增强型周期中断定时器)

 主打高效的周期性定时中断能力。它以递减计数器为核心,可从系统时钟中选择合适源并经分频后驱动计数。工作时,计数器从预设值开始递减,当与比较寄存器值匹配时触发中断,且支持自动重装载功能 —— 计数到 0 或匹配事件后,能自动将初始值重新载入计数器,无需软件干预即可实现稳定的周期性定时,非常适合需要固定间隔触发任务(如周期性数据采集、定时刷新)的场景,功能专一且响应高效。

#include "epit.h"
#include "../imx6ull/MCIMX6Y2.h"
#include "interrupt.h"
#include "led.h"void epit_irq_handler(void)//定时器EPIT中断
{if((EPIT1->SR & (1 << 0)) != 0) //SR位状态寄存器:0比较事件尚未发生;1发生比较事件。在0bit    {led_nor();EPIT1->SR |= (1 << 0); //该位写入一清除位:硬件高电平与1位清零}
}void epit1_init(void)//EPIT初始化
{unsigned int t;t = EPIT1->CR;//CR:控制寄存器,将当前的EPIT->CR寄存器的值放入t中t &= ~(3 << 24);//24,25bit先置0t |= (1 << 24);//24,25bit选择时钟源:01设置成外围时钟t |= (1 << 17);//17bit:EPIT计数器覆盖启用,0写入加载寄存器不会导致计数器被覆盖,1会t &= ~(0xFFF << 4);//4—15bit:逆时针预分频器值,此位字段用于确定在将时钟分频至计数器之前所进行的分频值。0x00:除以一t |= (65 << 4);//除以66;t |= (1 << 3);//3bit:计数器重新加载控制。0:当计数器达到零时,它会滚动至到OxFFF_FFF(自由运行模式)//1:当计数器达到零时,它会从模数寄存器重新加载(设置并忘记模式)t |= (1 << 2);//输出比较中断使能:      0比较中断禁用状态0比较中断已禁用//  1比较中断开启状态1比较中断已启用t |= (1 << 1);//EPIT使能模式。当ENMOD为1时,启动定时器,那么就从加载寄存器或者0xFFFFFFFF开始计数;//如果ENMOD=0,启动定时器后就从当前值开始计数。EPIT1->CR = t;EPIT1->LR = 1000*1000;//CR:加载寄存器EPIT1->CMPR = 0;//比较寄存器EPIT1->CNR = 1000*1000;//计数寄存器// 1.使能 EPIT1 中断GIC_EnableIRQ(EPIT1_IRQn);//2.中断优先级设置GIC_SetPriority(EPIT1_IRQn, 0);//3.注册中断处理函数system_interrupt_register(EPIT1_IRQn, epit_irq_handler);//启动 EPIT1 定时器:最后开启EPIT1->CR |= (1 << 0); 
}

整体实现了一个周期性中断定时器,当计数器从 1000000 递减到 0 时,会触发中断并翻转 LED 状态,然后自动重新加载计数,形成周期性定时功能。

2.GPT(通用定时器) 

则具备更灵活的多功能性。它支持向上、向下及双向计数模式,时钟源选择和分频配置同样灵活。除基础定时功能外,其核心优势在于输入捕获输出控制:输入捕获可检测外部信号边沿(如上升 / 下降沿)并锁存当前计数值,用于测量信号周期、脉宽等;比较功能不仅能触发中断,还可通过配置在外部引脚输出特定波形(如 PWM)。这种多模式、多接口的特性,使其适用于更复杂的场景,如电机调速(PWM 输出)、外部事件计时(捕获功能)等,灵活性远高于 EPIT。

#include "gpt.h"
#include "../imx6ull/MCIMX6Y2.h"/*** @brief 重置GPT1定时器* 作用:通过设置CR寄存器的软件复位位,将GPT1恢复到初始状态*/
void reset_gpt1()
{// GPT1->CR:GPT1控制寄存器// 第15位:软件复位位,置1触发GPT1复位GPT1->CR |= (1 << 15);// 等待复位完成:复位过程中第15位保持1,复位完成后自动清0while ((GPT1->CR & (1 << 15)) != 0);
}/*** @brief 初始化GPT1定时器,配置为自由运行模式用于计时*/
void gpt1_init(void)
{reset_gpt1();  // 先复位定时器,确保初始状态一致unsigned int t;t = GPT1->CR;  // 读取当前控制寄存器值,避免直接操作覆盖其他位// 配置时钟源(CR寄存器26-28位)t &= ~(7 << 26);  // 清除26-28位(时钟源选择位)// 此处未设置新值,默认使用外设时钟(具体需参考芯片手册)// 配置输出比较模式(CR寄存器18-19位)t &= ~(3 << 18);  // 清除18-19位,禁用输出比较功能(仅用于计时)// 使能计数器溢出中断(CR寄存器第9位)t |= (1 << 9);    // 置1:允许计数器溢出时产生中断// 配置计数模式(CR寄存器6-8位)t &= ~(7 << 6);   // 清除6-8位t |= (1 << 6);    // 设置为6-8位为001,选择"自由运行模式"(计数器从0x00000000递增到0xFFFFFFFF后回0)// 禁用暂停模式(CR寄存器第1位)t &= ~(1 << 1);   // 清0:禁止在调试模式下暂停计数器GPT1->CR = t;     // 写入配置值// 配置预分频器(PR寄存器0-11位)GPT1->PR &= ~(0xFFF << 0);  // 清除0-11位(预分频值)GPT1->PR |= (65 << 0);      // 设置预分频值为65,实际分频系数=65+1=66// 启动GPT1定时器(CR寄存器第0位)GPT1->CR |= (1 << 0);  // 置1:使能计数器开始计数
}/*** @brief 微秒级延时函数* @param us 延时的微秒数* 原理:利用GPT1的自由运行计数器计算经过的时间*/
void delay_us(unsigned int us)
{unsigned int counter = 0;          // 累计的计数次数unsigned int old_counter = 0, new_counter = 0;  // 用于保存计数器值old_counter = GPT1->CNT;  // 读取当前计数器值作为起始点while(1){new_counter = GPT1->CNT;  // 读取当前计数器值// 仅在计数器值变化时更新累计值(避免重复计算)if (old_counter != new_counter){// 处理计数器溢出(从0xFFFFFFFF回0的情况)if (old_counter < new_counter){// 未溢出:直接累加差值counter += new_counter - old_counter;}else{// 已溢出:累加"最大值到old_counter的差值" + "new_counter到0的差值"counter += 0xFFFFFFFF - old_counter + new_counter;}// 累计计数达到目标值时退出循环if (counter >= us){return;}old_counter = new_counter;  // 更新起始点}}
}/*** @brief 毫秒级延时函数* @param ms 延时的毫秒数* 原理:通过循环调用微秒延时函数实现*/
void delay_ms(unsigned int ms)
{while(ms--){delay_us(1000);  // 1毫秒 = 1000微秒}
}
1. 核心功能

这段代码实现了 i.MX6ULL 芯片中 GPT1(通用定时器 1)的初始化配置,并基于 GPT1 实现了微秒级(delay_us)和毫秒级(delay_ms)的延时功能。

2. 初始化流程(gpt1_init
  • 复位定时器:通过reset_gpt1函数触发软件复位,确保定时器初始状态一致
  • 配置控制寄存器(CR)
    • 选择时钟源(默认外设时钟)
    • 禁用输出比较功能(仅用于计时)
    • 使能计数器溢出中断(为后续扩展预留)
    • 设置为自由运行模式(计数器从 0 递增到 0xFFFFFFFF 后自动回 0)
    • 禁用调试暂停功能(确保计时不受调试影响)
  • 配置预分频器:设置分频系数为 66(输入时钟 / 66 作为计数时钟)
  • 启动定时器:使能计数器开始工作
3. 延时功能实现
  • delay_us

    • 记录起始时刻的计数器值(old_counter
    • 循环读取当前计数器值(new_counter),计算累计计数次数
    • 处理计数器溢出情况(从 0xFFFFFFFF 到 0 的跳变)
    • 当累计计数达到目标微秒数时退出
  • delay_ms

    • 通过循环调用delay_us(1000)实现毫秒级延时
    • 每次循环减少 1 毫秒计数,直到完成指定延时
4. 关键技术点
  • 自由运行模式:GPT1 计数器持续递增,溢出后自动归零,适合持续计时场景
  • 预分频配置:通过 66 分频降低计数频率,使计数器值与微秒级时间对应
  • 溢出处理:通过0xFFFFFFFF - old_counter + new_counter计算跨溢出的计数差值

整体逻辑清晰,先初始化定时器为自由运行模式,再利用其计数器值的变化实现精确延时,适用于需要精准时间控制的嵌入式场景(如传感器采样、外设时序控制等)。

http://www.dtcms.com/a/406066.html

相关文章:

  • HCIE 的云计算方向容易考过吗?该怎么准备考试?
  • 凤山县住房和城乡建设局网站wordpress中国能用吗
  • 从 EFI 到 GPT:深入理解现代计算机启动与磁盘分区技术
  • 计算机网络的性能指标和体系结构
  • 性能怪兽:GPT-5-Codex三大核心进化,重新定义AI编程
  • 网络通信协议全解析:HTTP/UDP/TCP核心要点
  • 郴州网站建设软件定制开发平台e盘网站建设
  • 在Unix/Linux中bash/sh/source以及./执行脚本的区别
  • 宜春公司做网站双语网站建设定制开发
  • Spring Boot 应用启动组件加载顺序与优先级详解
  • Spring Boot 事件发布与监听 观察者模式的实际应用
  • Sui Stack Messaging SDK:为 Web3 打造可编程通信
  • 光谱相机的未来趋势
  • 【Java后端】《Spring Boot Starter 原理详解》博客
  • 设计与绘制一个网站首页同学录wordpress
  • Vue2的生命周期
  • MySQL学习笔记04:MySQL InnoDB存储引擎核心机制深度解析
  • 中国企业网站建设响应式网站管理
  • 遇到不会的事,先写一写
  • 心理咨询 网站模版嘉兴网站建设技术开发
  • 【面试】Kafka / RabbitMQ / ActiveMQ
  • 新网站建设的工作总结文化网站建设需要的功能
  • 11.WPF 的命令处理事件--参数介绍
  • 旅游管理虚拟仿真实训室:打通理论与实践壁垒
  • FreeLong-无需训练即可延长视频生成时长
  • Lynx:新一代个性化视频生成模型,单图即可生成视频,重新定义身份一致性与视觉质量
  • 关于机器视觉中的”果冻效应“讲解:全局曝光 vs 卷帘曝光
  • 如何做百度的网站网站开发技术的雏形 cgi
  • 织梦医院网站源码6731官方网站下载
  • Transformer模型/注意力机制/目标检测/语义分割/图神经网络/强化学习/生成式模型/自监督学习/物理信息神经网络等