中级会员
- 积分
- 254
- 金钱
- 254
- 注册时间
- 2020-3-22
- 在线时间
- 35 小时
|
本帖最后由 YOKI 于 2020-3-26 13:51 编辑
/********************************************/
时间 :2020/03/26/
作者 :YOKI
导师 :正点原子 左忠凯
硬件 :正点原子 ALPHA I.MX LINUX 开发板
/*******************************************/
1、内核时钟配置
PLL1 [24*n]---------------->{CACRR[ARM_PODF]}---------->ARM_CLK_ROOT
外部时钟源[24MHz*n倍频]———————> 1~8分频(默认2分频)————————————> ARM内核频率
PLL1的时钟源为 650~1300MHz
设置 ARM 内核为 528 MHz 则 PLL1 为 1056 MHz 设置 2分频(CACRR[ARM_PODF]=001)
PLL1的设置:
CCRS(bit2)PLL1_SW_CLK_SEL : 0 pll1_main_clk
1 step_clk
CCRS(bit8) STEP_CLK_SEL : 0 24MHz OSC_CLK
1 secondary_clk
修改PLL1时钟时为了 ARM内核 处于运行状态应该 先给 内核一个临时时钟:step_clk
即 将CCRS(bit2)PLL1_SW_CLK_SEL 置为1
而 step_clk 的时钟来源又有两种:24M 晶振 和 secondary_clk
将 CCRS(bit8) STEP_CLK_SEL 置0 选择 24M 晶振
secondary_clk 也有两个来源: PLL2_main_CLK 528 MHz 和 PFD2 400 MHz
CCRS(bit3)SECONDARY_CLK_SEL : 0 PFD2 (400MHz)
1 PLL2 (528MHz)
然后再修改 PLL1 时钟主频
CCM_ANALOG_PLL_ARM 的 DIV_SEL 位(bit0-bit6) = n; 取值范围 54 - 108
f_out = (n*24)/2
以 1056 Mhz 为例 n=(1056*2)/24=88
CCM_ANALOG->PLL_ARM |= 88
设置CACRR的 ARM_PODF (bit0-bit2) 为 2分频
CCM->CACRR |= 0X01;
其它PLL时钟配置:
PLL2 固定默认频率 528M (NXP官方指定)/这也是step_clk 第2种时钟源/secondary_clk/的第1个时钟源(可以作为 ARM内核时钟 )
PLL3 固定默认频率 480M (NXP官方指定)
PLL4 -PLL7 时对应特定功能的时钟暂时不配置,也就是说 PLL 时钟配置完成,不过并没有结束
因为PLL2 和PLL3还有各自的 4个PFD (PFD0-PFD3) 要配置
/*********************************************************************************************/
先看 PLL2 的PFD配置:CCM_ANALOG_PFD_528n 寄存器
这是一个32位寄存器 每 8位 对应一个 PFD 由低到高依次是 PFD0 PFD1 PFD2 PFD3
以PFD0为例:
bit0—bit5: PFD0_FRAC 用来配置 PFD0 的频率 公式: 528*18/PFD0_FRAC 数值范围:12~35
bit6: PFD0_STABLE 只读位 不能配置
bit7: PFD0_CLKGATE 这是PFD0分频器时钟的使能位 置0使能 置1 关闭。
其他的几个 PFD1-PFD3 是一样的
PFD1:
bit8-bit13: PFD1_FRAC 配置 PFD1 的频率 公式: 528*18/PFD1_FRAC 数值范围:12~35
bit14: PFD1_STABLE 只读位 不能配置
bit15: PFD1_CLKGATE 这是PFD1分频器时钟的使能位 置0使能 置1 关闭。
PFD2: /这也是step_clk 第2种时钟源/secondary_clk/的第2个时钟源(可以作为 ARM内核时钟 )
bit16-bit21: PFD2_FRAC 配置 PFD2 的频率 公式: 528*18/PFD2_FRAC 数值范围:12~35
bit22: PFD2_STABLE 只读位 不能配置
bit23: PFD2_CLKGATE 这是PFD2分频器时钟的使能位 置0使能 置1 关闭。
PFD3:
bit24-bit29: PFD3_FRAC 配置 PFD3 的频率 公式: 528*18/PFD3_FRAC 数值范围:12~35
bit30: PFD3_STABLE 只读位 不能配置
bit31: PFD3_CLKGATE 这是PFD3分频器时钟的使能位 置0使能 置1 关闭。
那么配置 PFDx 频率只需要改写 公式 528*18/PFDx_FRAC 数值范围:12~35
CCM_ANALOG->PFD_528 &=~(0X3F3F3F3F); /* 0X3F=(0011 1111) 对低6位清0 */
CCM_ANALOG->PFD_528 |= (27<<0); /* 官方推荐PLL2的PFD0 为 352M Hz */
CCM_ANALOG->PFD_528 |= (16<<8); /* 官方推荐PLL2的PFD1 为 594M Hz */
CCM_ANALOG->PFD_528 |= (24<<16); /* PLL2的PFD2 为 396M Hz */
CCM_ANALOG->PFD_528 |= (32<<24); /* PLL2的PFD3 为 297M Hz */
/**********************************************************************************/
再看 PLL3 的PFD配置:CCM_ANALOG_PFD_480n 寄存器
和 CCM_ANALOG_PFD_528n 寄存器一样
这也是一个32位寄存器 每 8位 对应一个 PFD 由低到高依次是 PFD0 PFD1 PFD2 PFD3
以PFD0为例:
bit0—bit5: PFD0_FRAC 用来配置 PFD0 的频率 公式: 480*18/PFD0_FRAC 数值范围:12~35
bit6: PFD0_STABLE 只读位 不能配置
bit7: PFD0_CLKGATE 这是PFD0分频器时钟的使能位 置0使能 置1 关闭。
其他的几个 PFD1-PFD3 是一样的
PFD1:
bit8-bit13: PFD1_FRAC 配置 PFD1 的频率 公式: 480*18/PFD1_FRAC 数值范围:12~35
bit14: PFD1_STABLE 只读位 不能配置
bit15: PFD1_CLKGATE 这是PFD1分频器时钟的使能位 置0使能 置1 关闭。
PFD2:
bit16-bit21: PFD2_FRAC 配置 PFD2 的频率 公式: 480*18/PFD2_FRAC 数值范围:12~35
bit22: PFD2_STABLE 只读位 不能配置
bit23: PFD2_CLKGATE 这是PFD2分频器时钟的使能位 置0使能 置1 关闭。
PFD3:
bit24-bit29: PFD3_FRAC 配置 PFD3 的频率 公式: 480*18/PFD3_FRAC 数值范围:12~35
bit30: PFD3_STABLE 只读位 不能配置
bit31: PFD3_CLKGATE 这是PFD3分频器时钟的使能位 置0使能 置1 关闭。
那么配置 PFDx 频率只需要改写 公式 480*18/PFDx_FRAC 数值范围:12~35
CCM_ANALOG->PFD_480 &=~(0X3F3F3F3F); /* 0X3F=(0011 1111) 对低6位清0 */
CCM_ANALOG->PFD_480 |= (12<<0); /* 官方推荐PLL3的PFD0 为 480 M Hz */
CCM_ANALOG->PFD_480 |= (16<<8); /* 官方推荐PLL3的PFD1 为 540 M Hz */
CCM_ANALOG->PFD_480 |= (17<<16); /* 官方推荐PLL3的PFD2 为 508.2M Hz */
CCM_ANALOG->PFD_480 |= (19<<24); /* 官方推荐PLL3的PFD3 为 454.7M Hz */
/*********************************************************************************/
本节思考:
查看bsp_delay.c 文件看到之前写的延时函数
/***********************************
延时函数 一次循环大概1ms
n 为延时毫秒数 主频396Mhz
***********************************/
void delay(volatile unsigned int n)
{
while(n--)
{ delay_short(0X7FF);}
}
我们可以发现在本讲之前,我们的系统一直运行在 396M Hz 的频率下,那么 这个频率是那里来的?
1 PLL1 默认配置是 792M 2分频后 得到 396M
2 ARM内核 默认处于 step_clk 时钟运行状态,且 频率取自 PLL2的PFD2 为 396M Hz
PLL2 PFD2 的官方推荐频率就是 400M (取不到整数,取得最接近值为 396M )
我猜测 第二种可能性高一些。
本节编写过程中出现了一个玄学问题:
我的 ARM 内核主频修改函数如下:
void ARM_CLK_init (void)
{
// PLLx_PFD_CLK_init();
int PLL1_clk_mode = (CCM->CCSR>>2) & 0X01; /* 读取CCM_CCSR 的 bit2 */
/* 将 ARM 时钟暂时改为 step_clk 频率 24M */
if (PLL1_clk_mode == 0) /* ARM 时钟运行在 PLL1_mian_clk 时钟频率下 */
{
CCM->CCSR &= ~(1<<8); /* CCRS(bit8) STEP_CLK_SEL 置0 选择 24M 晶振 */
CCM->CCSR |= (1<<2); /* 将CCRS(bit2)PLL1_SW_CLK_SEL 置为1 选择 step_clk */
}
/* 将 ARM 时钟 PLL1_main_clk 频率配置为528M */
CCM_ANALOG->PLL_ARM |= (88 & 0X7F); /* 将 PLL1 主频设置为 1056 M */
CCM_ANALOG->PLL_ARM |= (1<<13); /* PLL1 输出使能*/
CCM->CACRR |= 0X01; /* 将 CACRR的 ARM_PODF (bit0-bit2) 为 2分频(001)*/
CCM->CCSR &= ~(1<<2); /* 将CCRS(bit2)PLL1_SW_CLK_SEL 置为0 选择 PLL1_mian_clk */
PLLx_PFD_CLK_init(); /* PLL2 PFDx 和 PLL3 PFDx 时钟配置*/
}
大家可以看到我的 PFD频率设置部分是 用函数 PLLx_PFD_CLK_init(); 封装起来的 函数内容如下:
void PLLx_PFD_CLK_init(void)
{
/* PLL2_PFD配置 */
CCM_ANALOG->PFD_528 &=~(0X3F3F3F3F); /* 0X3F=(0011 1111) 对低6位清0 */
CCM_ANALOG->PFD_528 |= (27<<0); /* 官方推荐PLL2的PFD0 为 352M Hz */
CCM_ANALOG->PFD_528 |= (16<<8); /* 官方推荐PLL2的PFD1 为 594M Hz */
CCM_ANALOG->PFD_528 |= (24<<16); /* 官方推荐PLL2的PFD2 为 396M Hz */
CCM_ANALOG->PFD_528 |= (32<<24); /* PLL2的PFD3 为 297M Hz */
/* PLL3_PFD配置 */
CCM_ANALOG->PFD_480 &=~(0X3F3F3F3F); /* 0X3F=(0011 1111) 对低6位清0 */
CCM_ANALOG->PFD_480 |= (12<<0); /* 官方推荐PLL3的PFD0 为 480 M Hz */
CCM_ANALOG->PFD_480 |= (16<<8); /* 官方推荐PLL3的PFD1 为 540 M Hz */
CCM_ANALOG->PFD_480 |= (17<<16); /* 官方推荐PLL3的PFD2 为 508.2M Hz */
CCM_ANALOG->PFD_480 |= (19<<24); /* 官方推荐PLL3的PFD3 为 454.7M Hz */
}
这部分内容和视频中是一样写法,但是直接写在 void ARM_CLK_init (void) 函数中系统却不运行(用led闪烁判断出来的),
但是我把它用void PLLx_PFD_CLK_init(void)函数 封装起来 再使用调用的方式放进 void ARM_CLK_init (void) ,系统
又可以运行,所以有点 迷惑 有大神 解答以下么?
/**********************************************************************************************/
个人总结: 时钟系统 PLL1主频修改 和 PDF配置 实验
这几个视频一直看了好几遍才感觉吃透了,然后才尝试自己写,中间有些不懂的就再回过去看视频和参考手册,虽然时钟树很复杂,
最后还是把这几讲掌握了,总之学习是一个痛并快乐着的过程,希望自己可以坚持下来,感谢 左萌主 在我前几个帖子下的回复,
有大神的护法果然会很开心。
以上注释和代码都是在学习 《正点原子 linux 第二期 裸机开发视频 P26~P28 第14讲 时钟系统 》 过程中
跟着 左萌主 学习并加入了一点点自己的思考写成的,作为一个小菜鸡,我大着胆子发出来跟大家一起记录学习
如果有帮助请大家自行参考、下载,如果 转载 请注明出处,并在论坛和我联系。如果有错误请大神指正!左萌主赛高!
作者 :YOKI
导师 :正点原子 左忠凯 (请允许我叫你一声导师吧)
硬件 :正点原子 ALPHA I.MX LINUX 开发板
/*********************************************************************************************/
|
|