OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4046|回复: 4

I.MX6系列时钟树中PLL_ARM问题

[复制链接]

6

主题

17

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2015-1-5
在线时间
16 小时
发表于 2023-2-19 11:44:24 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 黑暗主宰 于 2023-2-19 11:52 编辑

在“第十六章 主频和时钟配置实验”章节中
按照例程设置PLL_ARM主时钟,例程中采用的是,可以实现800M时钟配置
CCM_ANALOG->PLL_ARM = (1 << 13) | ((66 << 0) & 0X7F);

但是直接等于可能会影响其他bit位
我就把其分开写
    CCM_ANALOG->PLL_ARM &= ~(1<<13);
    CCM_ANALOG->PLL_ARM &= ~(0x7F<<0);

    CCM_ANALOG->PLL_ARM |= (((66 << 0) & 0X7F));
    CCM_ANALOG->PLL_ARM |= (1<<13);

这样反而实现不了时钟配置,这是为什么?

另外,在继续配置其他pll的过程中,发现在配置pll3(USB1, PFD-480)后,
方式1
CCM_ANALOG->PLL_ARM = (1 << 13) | ((66 << 0) & 0X7F);
方式2
CCM_ANALOG->PLL_ARM |= (((66 << 0) & 0X7F));
CCM_ANALOG->PLL_ARM |= (1<<13);
都可以实现800M时钟配置

这是为什么?




无法可挡
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2023-2-21 01:33:36 | 显示全部楼层
回复

使用道具 举报

3

主题

9

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2022-4-19
在线时间
6 小时
发表于 2023-2-22 22:02:17 | 显示全部楼层
很简单,PLL_ARM寄存器的DIV_SELECT bit是有范围的(54-108),你直接写0,会导致PLL1功能模块挂掉。或许你会问,你在DIV_SELECT清0之前有把enable bit写0,但是enable bit只是控制PLL1功能模块是否往外送clk,并不能决定PLL1功能模块是否产生clk以及产生的clk的大小
当DIV_SELECT bit写0,PLL1功能模块产生的clk会异常大,会直接导致PLL1功能模块挂掉,即使你后面有写入正确的DIV_SELECT bit的值,此异常也无法恢复。
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2024-8-20
在线时间
2 小时
发表于 2024-9-9 21:28:04 | 显示全部楼层
jauwang 发表于 2023-2-22 22:02
很简单,PLL_ARM寄存器的DIV_SELECT bit是有范围的(54-108),你直接写0,会导致PLL1功能模块挂掉。或许你 ...

void imx6u_clkinit(void) {
        uint32_t temp;
        /* 初始化6U主频率为528MHz */
        if (((CCM->CCSR >> 2) & 0x1U) == 0) {        //当前时钟使用pll1_main_clk
                CCM->CCSR &= ~(1U << 8);                        //设置step_clk = osc_clk=24MHz
                CCM->CCSR |= (1U << 2);                                //pll1_sw_clk = step_clk=24MHz
        }
        /* 设置PLL1=1056MHz */
        //CCM_ANALOG->PLL_ARM = (1u << 13) | ((66u << 0) & (0x7fu));
       
        temp = CCM_ANALOG->PLL_ARM;
        temp &= ~0X7FU;
        temp |= ((66U << 0) & 0X7FU);
        temp |= (1U << 13U);
        CCM_ANALOG->PLL_ARM = temp;

        CCM->CACRR = 0U;        //设置2分频
        CCM->CCSR &= ~(1U << 2);
}
请问我通过定义一个临时变量的方式来初始化PLL_ARM,为什么仍然无法达到效果?
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2024-8-20
在线时间
2 小时
发表于 2024-9-10 08:41:37 | 显示全部楼层
可以通过定义一个临时变量变量来解决这个问题。
/* 初始化时钟  */
void imx6u_clkinit(void) {
        volatile uint32_t _pall_arm;
        /* 初始化6U主频率为528MHz */
        if (((CCM->CCSR >> 2) & 0x1U) == 0) {        //当前时钟使用pll1_main_clk
                CCM->CCSR &= ~(1U << 8);                        //设置step_clk = osc_clk=24MHz
                CCM->CCSR |= (1U << 2);                                //pll1_sw_clk = step_clk=24MHz
        }
        /* 设置PLL1=1056MHz */
        //CCM_ANALOG->PLL_ARM = (1u << 13) | ((66u << 0) & (0x7fu));
        _pall_arm = CCM_ANALOG->PLL_ARM;
        _pall_arm = (_pall_arm & ~0x7FU) | ((66U << 0) & 0x7FU) | (1U << 13U);

        CCM_ANALOG->PLL_ARM = _pall_arm;

        CCM->CACRR = 0U;        //设置2分频
        CCM->CCSR &= ~(1U << 2);
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 22:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表