时钟讲解
1. 时钟晶振
- 32.768RTC时钟源
- 24主频及其他时钟源
2. 系统时钟详解
(不想详解了,都能查到)
2.1 7路PLL
为了方便生成时钟,生成了7路PLL
2.2 各路时钟分出来的PLD
2.3 时钟树
设置PLL和分频即可
3. 系统配置
3.1 系统主频配置
- 要设置ARM内核主频为528Mhz,设置CACRR寄存器的ARM_PODF作为二分频,然后设置PLL1为1056MHz即可,CACRR的ARM_PODF为bit2-bit0 (001)
- 设置PLL1为1056MHz PLL1 = pll1_sw_clk,他是有一个多路选择器
- pll1_sw_clk通过CCSR寄存器的pll1_sw_clk_sel选择,在修改PLL1时钟的时候,需要给它一个固定的备用的时钟step_clock, 首选使用24M,由CCSR的STEP_SEL
- 切换之后,就可以修改PLL1的值,CCM_ANALOG_PLL_ARM寄存器的DIV_SELECT的bit6-0,公式是PLL1 = 24 * 倍数/2,倍数等于88
- 在切换回PLL1之前,要设置CCARR寄存器为二分频,切记,要不超级溢出
代码:
/* 初始化时钟 */
void clk_init()
{
/* 设置主频位528MHz */
if(((CCM->CCSR >> 2) & 0x1) == 0) //判断是不是使用main的PLL
{
// 如果是,就换成备用时钟
CCM->CCSR &= ~(1 << 8); //step_clock = osc = 24M
CCM->CCSR |= (1<<2); //这样就使用了备用时钟24M
}
/* 设置PLL1等于1056 */
CCM_ANALOG->PLL_ARM |= (1 << 13);// ENANBLE位使能,使能输出
CCM_ANALOG->PLL_ARM |= (88 << 0) & 0x7f;//88
/* 设置二分频 */
CCM->CACRR |= 1 << 0;
/* 设置好了之后需要切换回main_clk */
CCM->CCSR &= ~(1 << 2);
}
4.PLL初始化
PLL2和PLL3。PLL2固定为528M,PLL3固定为480M
- 初始化PLL2_PFD0-PFD3 CCM_ANALOG_PFD_528用于设置4路PFD 比如PFD0 = 528*18/PFD0_FRAC, 设置PFD0_FRAC
- 初始化PLL3_PFD0-PFD3
void clk_init()
{
/* 设置主频位528MHz */
if(((CCM->CCSR >> 2) & 0x1) == 0) //判断是不是使用main的PLL
{
// 如果是,就换成备用时钟
CCM->CCSR &= ~(1 << 8); //step_clock = osc = 24M
CCM->CCSR |= (1<<2); //这样就使用了备用时钟24M
}
/* 设置PLL1等于1056 */
CCM_ANALOG->PLL_ARM |= (1 << 13);// ENANBLE位使能,使能输出
CCM_ANALOG->PLL_ARM |= (88 << 0) & 0x7f;//88
/* 设置二分频 */
CCM->CACRR |= 1 << 0;
/* 设置好了之后需要切换回main_clk */
CCM->CCSR &= ~(1 << 2);
/* 设置PLL2的四路PFD */
unsigned int reg = 0; //设置一个变量用于保存寄存器的值
reg = CCM_ANALOG->PFD_528;
reg &= ~(0x3f3f3f3f);//全部清零
reg |= (34<<24); // PLL2_PFD3 = 297
reg |= (24<<16); // PLL2_PFD2 = 400(396)
reg |= (16<<8); // PLL2_PFD1 = 594
reg |= (27<<0); // PLL2_PFD0 = 352
CCM_ANALOG->PFD_528 = reg;
/* 设置PLL3的四路PFD */
//480 * 18 / 倍数
reg = 0;
reg = CCM_ANALOG->PFD_480;
reg |= (19<<24); // PLL3_PFD3 = 454.7
reg |= (17<<16); // PLL3_PFD2 = 508.2
reg |= (16<<8); // PLL3_PFD1 = 540
reg |= (12<<0); // PLL3_PFD0 = 720
CCM_ANALOG->PFD_480 = reg;
}
4.其他时钟源外设
AHB PERCLK IPG
因为PERCLK和IPGclk要用到AHB的clk
AHB = 132
PERCLK = IPG = 66
#include "bsp_clk.h"
/*
* @description : 使能I.MX6U所有外设时钟
* @param : 无
* @return : 无
*/
void clk_enable(void)
{
CCM->CCGR0 = 0XFFFFFFFF;
CCM->CCGR1 = 0XFFFFFFFF;
CCM->CCGR2 = 0XFFFFFFFF;
CCM->CCGR3 = 0XFFFFFFFF;
CCM->CCGR4 = 0XFFFFFFFF;
CCM->CCGR5 = 0XFFFFFFFF;
CCM->CCGR6 = 0XFFFFFFFF;
}
/* 初始化时钟 */
void clk_init()
{
/* 设置主频位528MHz */
if(((CCM->CCSR >> 2) & 0x1) == 0) //判断是不是使用main的PLL
{
// 如果是,就换成备用时钟
CCM->CCSR &= ~(1 << 8); //step_clock = osc = 24M
CCM->CCSR |= (1<<2); //这样就使用了备用时钟24M
}
/* 设置PLL1等于1056 */
CCM_ANALOG->PLL_ARM |= (1 << 13);// ENANBLE位使能,使能输出
CCM_ANALOG->PLL_ARM |= (88 << 0) & 0x7f;//88
/* 设置二分频 */
CCM->CACRR |= 1 << 0;
/* 设置好了之后需要切换回main_clk */
CCM->CCSR &= ~(1 << 2);
/* 设置PLL2的四路PFD */
unsigned int reg = 0; //设置一个变量用于保存寄存器的值
reg = CCM_ANALOG->PFD_528;
reg &= ~(0x3f3f3f3f);//全部清零
reg |= (34<<24); // PLL2_PFD3 = 297
reg |= (24<<16); // PLL2_PFD2 = 400(396)
reg |= (16<<8); // PLL2_PFD1 = 594
reg |= (27<<0); // PLL2_PFD0 = 352
CCM_ANALOG->PFD_528 = reg;
/* 设置PLL3的四路PFD */
//480 * 18 / 倍数
reg = 0;
reg = CCM_ANALOG->PFD_480;
reg |= (19<<24); // PLL3_PFD3 = 454.7
reg |= (17<<16); // PLL3_PFD2 = 508.2
reg |= (16<<8); // PLL3_PFD1 = 540
reg |= (12<<0); // PLL3_PFD0 = 720
CCM_ANALOG->PFD_480 = reg;
/* 配置AHB时钟 */
//选择CBCMR的PRE_PERIPH_CLK_SEL配置使用PLL2_PDF2
CCM->CBCMR &= ~(3 << 18);
CCM->CBCMR |= (1 << 18); //PRE_PERIPH_CLK_SEL
//CBCDR寄存器PRE_PERIPH_CLK_SEL外设主时钟为PLL2
CCM->CBCDR &= ~(1 << 25);
//注意设置完毕之后一定要等握手信号不忙!
while(CCM->CDHIPR & (1 << 5)); //·判断遮盖为真
#if 0
//这里其实不需要设置3分频,bootrom已经设置好啦,强行设置可能时钟卡死
//最后再设置分频器 396/3
CCM->CBCDR &= ~(7 << 10); //对3位清楚
CCM->CBCDR |= (2 << 10);
//注意设置完毕之后一定要等握手信号不忙!
while(CCM->CDHIPR & (1 << 1)); //·判断遮盖为真
#endif
/* IPG = 66 */
CCM->CBCDR &= ~(3 << 8);
CCM->CBCDR |= (1 << 8);
/* PERCLK = 66 选择AHB为时钟源*/
//CSCMR PERCLK_PODF
// 看原理图可知,要先设置CBCDR的IPG_PODF,二分频设置好之后再上面那个,等于一举两得
// PERCLK_CLK_SEL为0表示使用ipg
CCM->CSCMR1 &= ~(1 << 6);
CCM->CSCMR1 &= ~(0x3f << 0); //虽然使用了3位,但实际6位
CCM->CSCMR1 |= (0 << 0); //1分频
}
5. 有时候代码烧不进去可以make clean一下
主要是给自己看的,所以肯定会出现很多错误哈哈哈哈哈
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律