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

嵌入式硬件——IMX6ULL时钟配置

一、时钟系统初始化准备

  • 关闭可能影响配置的模块(如Cache、MMU),避免时钟切换时内核不稳定;
  • 明确配置目标(如内核主频528MHz、AHB=132MHz、IPG=66MHz)。

读取并修改SCTLR寄存器(CP15协处理器):

  • 通过MRC指令读取CP15的SCTLR寄存器(系统控制寄存器);
  • 清零V位(bit13,允许异常向量表重定位)、I位(bit12,关闭I Cache)、C位(bit2,关闭D Cache)等,确保配置过程中无干扰。

确认外设时钟使能准备:

  • 后续需通过CCM_CCGR0~CCM_CCGR6寄存器启用外设时钟,初始可先全局使能(如enable_clocks函数,设置所有CCGR寄存器为0xFFFFFFFF)。

二、配置核心PLL(重点为ARM_PLL、PLL2、PLL3)

  • 配置ARM_PLL(PLL1)以设定内核主频;
  • 确认PLL2(528MHz)、PLL3(480MHz)的固定倍频(无需修改,仅需后续配置其PFD)。

操作步骤(以“内核主频528MHz”为例)
切换内核临时时钟源(避免PLL配置时内核停摆):

  • 配置CCM_CCSR寄存器(时钟控制状态寄存器):
    • CCM->CCSR &= ~(1 << 8):设置STEP_SEL位,使step_clk时钟源为24MHz晶振;
    • CCM->CCSR |= (1 << 2):设置PLL1_SW_CLK_SEL位,将内核时钟切换到step_clk(临时24MHz)。

配置ARM_PLL(PLL1)为1056MHz:

  • 操作CCM_ANALOG_PLL_ARM寄存器(PLL1配置寄存器):
    • 清零BYPASS位(bit16),禁用PLL旁路;
    • 设置DIV_SELECT位(bit12~bit0):根据公式Fout = Fin × (DIV_SELECT / 2.0),代入Fout=1056MHzFin=24MHz,计算得DIV_SELECT=88
    • 置位ENABLE位(bit13),使能PLL1输出。

设置内核分频(得到目标主频):

  • 配置CCM_CACRR寄存器(ARM时钟分频寄存器):
    • CCM->CACRR |= (1 << 0):设置ARM_PODF位为2分频(1056MHz / 2 = 528MHz)。

切换回PLL1主时钟:

  • CCM->CCSR &= ~(1 << 2):将PLL1_SW_CLK_SEL位清零,内核时钟切换回pll1_main_clk(528MHz)。

三、配置PLL2与PLL3的PFD(相位分数分频器)

  • 为外设提供多样化的根时钟源(如PLL2_PFD2供AHB根时钟),需按NXP推荐频率配置8路PFD(PLL2 4路+PLL3 4路)。

关键公式与配置步骤
PFD频率计算:

  • PLL2_PFDn:Fout = 528MHz × 18 / PFDn_FRACPFDn_FRAC范围12~35);
  • PLL3_PFDn:Fout = 480MHz × 18 / PFDn_FRACPFDn_FRAC范围12~35)。

按NXP推荐值配置PFD:

PFD模块推荐频率计算得PFDn_FRAC操作寄存器
PLL2_PFD0352MHz27(528×18/27=352)CCM_ANALOG->PFD_528
PLL2_PFD1594MHz16(528×18/16=594)CCM_ANALOG->PFD_528
PLL2_PFD2396MHz24(528×18/24=396)CCM_ANALOG->PFD_528
PLL2_PFD3297MHz32(528×18/32=297)CCM_ANALOG->PFD_528
PLL3_PFD0720MHz12(480×18/12=720)CCM_ANALOG->PFD_480
PLL3_PFD1540MHz16(480×18/16=540)CCM_ANALOG->PFD_480
PLL3_PFD2508.2MHz17(480×18/17≈508)CCM_ANALOG->PFD_480
PLL3_PFD3454.7MHz19(480×18/19≈455)CCM_ANALOG->PFD_480

寄存器操作细节:

  • 先清零PFDn_FRAC位(如CCM_ANALOG->PFD_528 &= ~(0x3F << 0)),避免残留值;
  • 清零PFDn_CLKGATE位(如CCM_ANALOG->PFD_528 &= ~(1 << 7)),使能PFD输出。

四、配置AHB/IPG/PERCLK根时钟

  • 为外设提供标准时钟(AHB=132MHz、IPG=66MHz、PERCLK=66MHz),需从PFD选择输入时钟并分频。

配置步骤(以“PLL2_PFD2=396MHz为输入”为例)
配置AHB_CLK_ROOT(132MHz):

  • 选择输入时钟:配置CCM_CBCMR寄存器的PRE_PERIPH_CLK_SEL位(bit19~18),选择PLL2_PFD2为输入;
  • 分频设置:配置CCM_CBCDR寄存器的AHB_PODF位(bit12~10),设置为3分频(396MHz / 3 = 132MHz)。

配置IPG_CLK_ROOT(66MHz):

  • 输入时钟为AHB_CLK_ROOT,配置CCM_CBCDRIPG_PODF位(bit9~8),设置为2分频(132MHz / 2 = 66MHz)。

配置PERCLK_CLK_ROOT(66MHz):

  • 输入时钟为IPG_CLK_ROOT,配置CCM_CSCMR1PERCLK_PODF位(bit6~0),设置为1分频(66MHz / 1 = 66MHz)。

五、使能外设时钟

  • 为具体外设(如GPIO、UART、PWM)启用时钟,避免未使用外设耗电。

操作方式
全局使能(调试阶段便捷使用):

  • 通过enable_clocks函数,设置CCM_CCGR0~CCM_CCGR60xFFFFFFFF,启用所有外设时钟。

按需使能(量产阶段节能):

  • 每个CCM_CCGRx寄存器的每2位控制一个外设时钟,例如:
    • CCM_CCGR0bit31~30控制GPIO2时钟,设置为11(除停止模式外均使能);
    • 公式:CCM->CCGRx |= (0x03 << n)n为外设对应的位偏移)。

六、时钟配置验证

  • 确认时钟配置是否生效(如内核主频、根时钟频率)。

验证方法
软件验证:

  • 读取CCM_CACRRARM_PODF位,确认分频是否正确;
  • 读取CCM_ANALOG_PLL_ARMDIV_SELECT位,确认PLL1倍频是否正确;
  • 通过延时函数间接验证。

硬件验证:

  • 若开发板有示波器接口,可测量外设时钟引脚(如UART的PCLK),确认频率是否匹配配置值。

关键代码参考(基于clock.c

// 1. 全局使能外设时钟
void enable_clocks(void) {CCM->CCGR0 = 0xFFFFFFFF;CCM->CCGR1 = 0xFFFFFFFF;CCM->CCGR2 = 0xFFFFFFFF;CCM->CCGR3 = 0xFFFFFFFF;CCM->CCGR4 = 0xFFFFFFFF;CCM->CCGR5 = 0xFFFFFFFF;CCM->CCGR6 = 0xFFFFFFFF;
}// 2. 核心时钟配置(内核528MHz、AHB=132MHz、IPG=66MHz)
void init_clock(void) {unsigned int t;// 阶段2:切换内核临时时钟源(24MHz)CCM->CCSR &= ~(1 << 8);   // STEP_SEL=0,step_clk=24MHzCCM->CCSR |= (1 << 2);    // PLL1_SW_CLK_SEL=1,内核时钟=step_clk// 阶段2:配置ARM_PLL(PLL1=1056MHz)t = CCM_ANALOG->PLL_ARM;t &= ~(3 << 14);          // 清除BYPASS_CLK_SRCt |= (1 << 13);           // 使能PLL1t &= ~(0x7F << 0);        // 清除DIV_SELECTt |= (88 << 0);           // DIV_SELECT=88(1056MHz=24×88/2)CCM_ANALOG->PLL_ARM = t;CCM->CACRR |= (1 << 0);   // ARM_PODF=2分频(528MHz)// 阶段2:切换回PLL1主时钟CCM->CCSR &= ~(1 << 2);   // PLL1_SW_CLK_SEL=0,内核时钟=pll1_main_clk// 阶段3:配置PLL2_PFD(528MHz衍生)t = CCM_ANALOG->PFD_528;t &= ~((0x3F << 0) | (0x3F << 8) | (0x3F << 16) | (0x3F << 24));t &= ~((1 << 7) | (1 << 15) | (1 << 23) | (1 << 31));  // 使能PFD输出t |= (27 << 0) | (16 << 8) | (24 << 16) | (32 << 24);  // PFD0~PFD3配置CCM_ANALOG->PFD_528 = t;// 阶段3:配置PLL3_PFD(480MHz衍生)t = CCM_ANALOG->PFD_480;t &= ~((0x3F << 0) | (0x3F << 8) | (0x3F << 16) | (0x3F << 24));t &= ~((1 << 7) | (1 << 15) | (1 << 23) | (1 << 31));  // 使能PFD输出t |= (12 << 0) | (16 << 8) | (17 << 16) | (19 << 24);  // PFD0~PFD3配置CCM_ANALOG->PFD_480 = t;// 阶段4:配置AHB/IPG/PERCLK根时钟t = CCM->CBCMR;t &= ~(3 << 18);t |= (1 << 18);           // PRE_PERIPH_CLK_SEL=PLL2_PFD2CCM->CBCMR = t;t = CCM->CBCDR;t &= ~((7 << 10) | (3 << 8));t |= (2 << 10) | (1 << 8);  // AHB_PODF=3分频(132MHz)、IPG_PODF=2分频(66MHz)CCM->CBCDR = t;CCM->CSCMR1 &= ~(0X3F << 0);  // PERCLK_PODF=1分频(66MHz)// 阶段5:全局使能外设时钟enable_clocks();
}

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

相关文章:

  • 【用androidx.camera拍摄景深合成照片】
  • linux安装google chrome 谷歌浏览器
  • 从零起步学习Redis || 第二章:Cache Aside Pattern(旁路缓存模式)以及优化策略
  • 两性做受技巧视频网站喊别人做的网站不肯给代码
  • ESP32-S3入门第八天:往期知识回顾与实战练习
  • Claude Code 实战指南(三):AI辅助开发工作流 Spec Workflow MCP教程
  • 红帽认证含金量怎么样?适合哪些人?
  • 宣传的网站开发需要多少钱步骤的英文
  • 选择一款拖拽式界面的vscode扩展程序制作Python界面
  • Android开发-屏幕变更事件
  • 十大咨询公司排行榜aso优化师主要是干嘛的
  • LeetCode第1346题 - 检查整数及其两倍数是否存在
  • 【Leetcode hot 100】207.课程表
  • 搜索引擎高级搜索技巧
  • 2.3 物理层设备 (答案见原书 P48)
  • 华为OBS obsutil使用
  • 租购同权七年之痒:政策善意如何变现?
  • 【Linux操作系统】基础开发工具
  • 老年ai模拟恋爱抖音快手微信小程序看广告流量主开源
  • 知名的网站制作公司需要多少钱企业宣传网站模板下载
  • 深圳横岗做网站的网站品牌形象设计怎么做
  • 社区网站推广方案百度百家号注册
  • 编程竞赛高频考点
  • Linux 程序使用 STDOUT 打印日志导致程序“假死”?一次线上 Bug 的深度排查与解决
  • (一)routeros命令笔记:开局篇
  • 网站推广模式一份完整的项目计划书
  • 基于STM32设计的智能安全头盔_299
  • ​VR应急安全学习机,提升应对自然灾害时自救互救的应急技能
  • app网站建设公司竞彩网站建设
  • pytorch基本运算-torch.normal()函数输出多维数据时,如何绘制正态分布函数图