news 2026/4/16 14:58:37

学习笔记——时钟系统与定时器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
学习笔记——时钟系统与定时器

时钟系统与定时器

一、基本概念定义

1. 核心术语解析

  • 定时器 (Timer):通过对已知频率的时钟信号进行计数,实现时间测量、延时控制或事件计数功能的硬件模块或软件机制。

  • 时钟 (Clock):在电子系统中产生稳定周期性振荡信号的电路或组件,为数字电路提供同步时序基准。

  • 实时时钟 (RTC):独立供电的时间保持模块,在主系统电源关闭时继续提供精确的日历和时间信息。

2. 频率单位说明

  • 频率计算:1 MHz = 1,000 × 1,000 = 1,000,000 Hz

  • 存储计算:1 MByte = 1,024 × 1,024 = 1,048,576 Byte

二、时钟硬件架构

1. 时钟源:晶体振荡器

工作原理

石英晶体 → 切割成音叉形状 → 施加电压 → 压电效应 → 稳定机械振荡 → 电信号输出 频率特性:24 MHz(i.MX6ULL基准频率) 稳定性:±10 ppm(百万分之十)

2. 锁相环电路 (PLL)

功能:频率合成与倍频

输入频率 F_in → 鉴相器 → 环路滤波器 → 压控振荡器 → 输出频率 F_out 数学模型:F_out = F_in × (N/D) 其中:N为倍频因子,D为分频因子

3. 预分频器 (Prescaler)

功能:整数分频

F_out = F_in / M M为整数分频系数(1-64)

4. 相位分数分频器 (PFD)

功能:分数分频,实现非整数分频比

F_out = F_in × (N/M) 可精确控制输出相位

三、i.MX6ULL时钟系统架构

1. PLL配置总览

外部晶振 (24MHz) ↓ ├── PLL1 (ARM PLL) - Cortex-A7内核时钟,可配置至1056MHz ├── PLL2 (528 PLL) - 系统PLL,固定528MHz ├── PLL3 (480 PLL) - USB1 PLL,固定480MHz ├── PLL4 (Audio PLL) - 音频设备 ├── PLL5 (Video PLL) - 视频设备 ├── PLL6 (Ethernet PLL)- 以太网设备 └── PLL7 (USB2 PLL) - USB2设备

2. PFD配置

每个主PLL包含4个PFD通道:

PLL2 (528MHz) PFD通道: PFD0: 352MHz PFD1: 594MHz PFD2: 396MHz PFD3: 297MHz PLL3 (480MHz) PFD通道: PFD0: 720MHz PFD1: 540MHz PFD2: 508.2MHz PFD3: 454.7MHz

3. 时钟树关键节点

ARM内核时钟路径: 24MHz晶振 → PLL1倍频 → 二分频 → Cortex-A7内核 (1056MHz) 系统总线时钟: 24MHz → PLL2 (528MHz) → 各PFD通道 → 多路选择器 → 分频器 → 外设时钟

四、时钟配置代码实现

1. ARM PLL配置流程

void configure_arm_pll(void) { /* 步骤1:切换到安全时钟源 */ // CBCMR[18:19] PRE_PERIPH_CLK_SEL = 00 (osc_clk) CCM->CBCMR &= ~(3 << 18); // CBCDR[25] PERIPH_CLK_SEL = 0 (选择step_clk) CCM->CBCDR &= ~(1 << 25); /* 步骤2:旁路PLL,使用24MHz直接工作 */ // CBCDR[25] PERIPH_CLK_SEL = 1 (选择pll1_sw_clk) CCM->CBCDR |= (1 << 25); /* 步骤3:配置PLL1参数(关键安全步骤)*/ // 先设置输出分频,避免过高频率 CCM_ANALOG->PLL_ARM |= (1 << 19); // 使能二分频 // 配置倍频因子:N=88 CCM_ANALOG->PLL_ARM &= ~0x7F; // 清除DIV_SELECT CCM_ANALOG->PLL_ARM |= (88 << 0); // DIV_SELECT=88 // 计算:24MHz × 88 = 2112MHz,二分频后=1056MHz /* 步骤4:等待PLL锁定 */ while(!(CCM_ANALOG->PLL_ARM & (1 << 31))); // 检查LOCK位 /* 步骤5:切换回PLL输出 */ CCM->CBCDR &= ~(1 << 25); // PERIPH_CLK_SEL=0 }

2. 系统时钟配置

// AHB_CLK_ROOT配置为132MHz void configure_ahb_clk(void) { // 选择时钟源:PLL2 PFD2 (396MHz) CCM->CBCMR |= (1 << 18); // PRE_PERIPH_CLK_SEL=01 CCM->CBCDR &= ~(1 << 25); // PERIPH_CLK_SEL=0 // 设置AHB分频:396MHz ÷ 3 = 132MHz CCM->CBCDR &= ~(7 << 10); // 清除AHB_PODF CCM->CBCDR |= (2 << 10); // AHB_PODF=010 (3分频) } // IPG_CLK_ROOT配置为66MHz void configure_ipg_clk(void) { // AHB时钟 ÷ 2 = 66MHz CCM->CBCDR &= ~(3 << 8); // 清除IPG_PODF CCM->CBCDR |= (1 << 8); // IPG_PODF=01 (2分频) } // PERCLK_CLK_ROOT配置为66MHz void configure_perclk(void) { // 选择IPG时钟作为源 CCM->CSCMR1 &= ~(1 << 6); // PERCLK_CLK_SEL=0 // 设置分频系数 CCM->CSCMR1 &= ~(0x3F << 0); // 清除PERCLK_PODF CCM->CSCMR1 |= (0 << 0); // PERCLK_PODF=0 (1分频) }

五、定时器工作原理

1. 51单片机定时器

基本结构

  • Timer0/Timer1:16位定时器/计数器

  • 工作模式

    • 模式0:13位定时器

    • 模式1:16位定时器

    • 模式2:8位自动重装

    • 模式3:双8位定时器

配置示例

// Timer0 16位定时器配置 void timer0_init(void) { TMOD &= 0xF0; // 清除Timer0配置位 TMOD |= 0x01; // 模式1:16位定时器 // 计算初值(12MHz晶振,1ms定时) // 机器周期 = 1μs,计数1000次=1ms TH0 = (65536 - 1000) / 256; TL0 = (65536 - 1000) % 256; ET0 = 1; // 使能Timer0中断 TR0 = 1; // 启动Timer0 } // 中断服务程序 void timer0_isr() interrupt 1 { TH0 = (65536 - 1000) / 256; // 手动重装初值 TL0 = (65536 - 1000) % 256; // 用户处理代码 }

2. i.MX6ULL EPIT定时器

特性

  • 32位递减计数器

  • 自动重载功能

  • 精确周期性中断

1秒LED闪烁实验

// EPIT1初始化 void epit1_init(void) { // 1. 禁用EPIT1 EPIT1->CR = 0; // 2. 配置控制寄存器 EPIT1->CR = (1 << 24) | // ENMOD:计数器初始加载值 (1 << 3) | // OCIEN:使能比较中断 (1 << 2) | // RLD:使能重载模式 (0 << 1) | // OM:输出模式(比较输出) (0 << 0); // EN:暂不使能 // 3. 设置预分频(66MHz ÷ 66 = 1MHz) EPIT1->CR |= (65 << 4); // PRESCALAR = 65 // 4. 设置加载值(1MHz时钟,1秒计数) EPIT1->LR = 1000000; // 加载寄存器 // 5. 设置比较值 EPIT1->CMPR = 0; // 比较寄存器 // 6. 清除中断标志 EPIT1->SR |= (1 << 0); // 7. 使能中断 enable_irq(EPIT1_IRQn); // 8. 启动定时器 EPIT1->CR |= (1 << 0); } // EPIT1中断服务函数 void epit1_irq_handler(void) { if (EPIT1->SR & (1 << 0)) { EPIT1->SR |= (1 << 0); // 清除中断标志 gpio_toggle(LED_GPIO); // 翻转LED } }

3. GPT定时器

特性

  • 32位递增计数器

  • 输入捕获功能

  • 比较输出功能

  • 多种工作模式

精准延时函数实现

// GPT1微秒级延时 void gpt_delay_us(uint32_t us) { // 1. 复位GPT1 GPT1->CR = (1 << 15); // SWR:软件复位 // 2. 配置GPT1 GPT1->CR = (0 << 9) | // CLKSRC:ipg_clk (66MHz) (1 << 6) | // ENMOD:使能模式 (0 << 1) | // FRR:自由运行模式 (0 << 0); // EN:暂不使能 // 3. 设置预分频(66MHz ÷ 66 = 1MHz) GPT1->PR = 65; // 分频寄存器 // 4. 启动GPT1 GPT1->CR |= (1 << 0); // 5. 获取起始计数值 uint32_t start_time = GPT1->CNT; // 6. 等待指定时间 uint32_t target_cnt = us; // 1MHz时钟,1计数=1μs while ((GPT1->CNT - start_time) < target_cnt) { // 处理计数器溢出 if (GPT1->CNT < start_time) { target_cnt -= (0xFFFFFFFF - start_time + GPT1->CNT + 1); start_time = GPT1->CNT; } } // 7. 停止GPT1 GPT1->CR &= ~(1 << 0); } // GPT1毫秒级延时 void gpt_delay_ms(uint32_t ms) { for (uint32_t i = 0; i < ms; i++) { gpt_delay_us(1000); } }

六、重点问题详解

问题1:PLL、Prescaler、PFD的作用

模块功能数学关系应用场景
PLL频率合成与倍频F_out = F_in × N/D产生高频系统时钟
Prescaler整数分频F_out = F_in / M降低时钟频率
PFD分数分频F_out = F_in × N/M精确频率控制

问题2:i.MX6ULL PLL和PFD数量

  • PLL总数:7个

    • PLL1:ARM PLL(1056MHz)

    • PLL2:System PLL(528MHz)

    • PLL3:USB1 PLL(480MHz)

    • PLL4:Audio PLL

    • PLL5:Video PLL

    • PLL6:Ethernet PLL

    • PLL7:USB2 PLL

  • PFD总数:28个(每个PLL有4个PFD通道)

问题3:ARM PLL配置流程

  1. 时钟源切换:选择24MHz OSC作为临时时钟源

  2. PLL旁路:绕过PLL,直接使用低频时钟

  3. 参数配置

    • 设置输出分频(安全措施)

    • 配置倍频因子(N=88)

    • 等待PLL锁定

  4. 时钟切换:切回PLL输出时钟

  5. 频率验证:确认时钟稳定工作

问题4:EPIT与GPT工作原理对比

特性EPITGPT
计数方向递减计数递增计数
重载方式自动重载多种模式
主要用途周期性中断通用定时
输出模式比较输出捕获/比较
时钟源ipg_clk/ipg_clk_highfreq多种选择

问题5:时钟树中各模块作用

模块功能描述在时钟树中的位置
锁相环PLL频率提升,将低频时钟倍频到工作频率时钟树前端
预分频器整数分频,降低时钟频率各级时钟通路
相位分数分频器精确分数分频,实现任意频率比PLL输出后
多路选择器时钟源选择,动态切换时钟各时钟节点
CG门时钟门控,低功耗控制各外设时钟入口

七、实践注意事项

1. 时钟配置安全规范

// 错误示例:直接修改PLL倍频因子 CCM_ANALOG->PLL_ARM |= (88 << 0); // 危险!可能造成系统崩溃 // 正确示例:安全的PLL配置流程 // 1. 切换到低频时钟源 // 2. 设置输出分频 // 3. 配置倍频因子 // 4. 等待锁定 // 5. 切换回高频时钟

2. 定时器精度考虑因素

  1. 时钟源精度:晶体振荡器的稳定度

  2. 分频误差:整数分频的量化误差

  3. 中断延迟:中断响应时间

  4. 软件开销:中断服务程序执行时间

3. 调试技巧

// 时钟频率测量方法 void measure_clock_frequency(void) { uint32_t start, end; // 使用GPT测量1秒内计数 GPT1->CR = 0; GPT1->CR = (1 << 6) | (1 << 0); // ENMOD + EN GPT1->PR = 0; // 不分频 start = GPT1->CNT; gpt_delay_ms(1000); // 延时1秒 end = GPT1->CNT; printf("频率:%lu Hz\n", end - start); }

八、总结

时钟系统和定时器是嵌入式系统的核心基础组件,理解其工作原理和配置方法对于系统稳定性、性能和功耗控制至关重要。i.MX6ULL提供了灵活的时钟架构和多种定时器,能够满足不同应用场景的需求。配置时钟时应遵循安全规范,定时器使用时要考虑精度和实时性要求。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 11:14:17

想做语音情绪监控?先试试这个开箱即用的镜像环境

想做语音情绪监控&#xff1f;先试试这个开箱即用的镜像环境 你有没有遇到过这样的场景&#xff1a;客服通话中客户语气越来越急促&#xff0c;但系统只记录了“用户投诉物流延迟”这行文字&#xff1b;会议录音转写后全是干巴巴的发言内容&#xff0c;却漏掉了关键的停顿、笑…

作者头像 李华
网站建设 2026/4/16 12:21:03

从0到1部署Qwen2.5-7B微调环境,无需配置一步到位

从0到1部署Qwen2.5-7B微调环境&#xff0c;无需配置一步到位 你是否经历过这样的场景&#xff1a;想快速验证一个微调想法&#xff0c;却卡在环境搭建上——CUDA版本不匹配、依赖冲突、显存报错、LoRA参数调了八百遍还是OOM&#xff1f;更别说还要手动下载模型、配置tokenizer…

作者头像 李华
网站建设 2026/4/16 11:02:41

Qwen3-4B-Instruct推理延迟高?GPU内核优化部署实战案例

Qwen3-4B-Instruct推理延迟高&#xff1f;GPU内核优化部署实战案例 1. 问题现场&#xff1a;为什么“开箱即用”反而卡在了第一步&#xff1f; 你刚拉起 Qwen3-4B-Instruct-2507 的镜像&#xff0c;显存占用看着健康&#xff0c;GPU 利用率也跳到了 70%&#xff0c;可一输入“…

作者头像 李华
网站建设 2026/4/16 11:01:04

ubuntu / kali 将 /dev/sdb1 安全挂载为 /home 的完整实战指南(避坑版)

摘要 《将 /dev/sdb1 安全挂载为 /home 的完整实战指南》提供了在不重装系统、不丢失数据的情况下&#xff0c;将 /home 目录迁移到大容量新磁盘的详细步骤。关键操作包括&#xff1a;临时挂载新磁盘到/mnt/newhome&#xff0c;使用rsync完整同步/home数据&#xff0c;备份原/…

作者头像 李华
网站建设 2026/4/15 16:47:45

Qwen3-Embedding-4B与text-embedding-3-large对比评测

Qwen3-Embedding-4B与text-embedding-3-large对比评测 1. Qwen3-Embedding-4B核心能力解析 1.1 模型定位与技术背景 Qwen3-Embedding-4B 是通义千问&#xff08;Qwen&#xff09;家族中专为文本嵌入任务设计的中等规模模型&#xff0c;属于 Qwen3 Embedding 系列的重要成员。…

作者头像 李华
网站建设 2026/4/16 11:09:56

Qwen All-in-One交通调度辅助:语音指令解析实战

Qwen All-in-One交通调度辅助&#xff1a;语音指令解析实战 1. 为什么交通调度需要“听懂话”的AI&#xff1f; 你有没有遇到过这样的场景&#xff1a; 调度中心值班员正盯着大屏&#xff0c;突然接到一线人员电话&#xff1a;“西三环辅路有辆公交车抛锚了&#xff0c;后方已…

作者头像 李华