修改 AHB_PODF
时不能直接对寄存器中的相应位进行清零,因为 0 对应分频系数 1,会将 AHB
设置为 396 MHz 超过了其最大频率 132 MHz,导致死机。
// 错误代码
CCM->CBCDR &= ~(7 << 10);/* CBCDR 的 AHB_PODF 清零 */
CCM->CBCDR |= 2 << 10; /* AHB_PODF 3 分频, AHB_CLK_ROOT=132MHz */
// 正确代码
CCM->CBCMR &= ~(3 << 18); // 清除 pre_periph_clk 时钟源设置
CCM->CBCMR |= (1 << 18); // pre_periph_clk 时钟源选择 PLL2_PFD2,即396MHZ
CCM->CBCDR &= ~(1 << 25); // PERIPH_CLK_SEL设置0,periph_clk = pre_periph_clk
while (CCM->CDHIPR & (1 << 5)); // 等待 PERIPH_CLK_SEL 握手完成
IOMUXC_GPR->GPR1 &= ~(1 << 26); // 关闭 AHB_ROOT_CLK 时钟
CCM->CBCDR = ((CCM->CBCDR & ~(7 << 10)) | (2 << 10)); // AHB分频系数3,396 / 3 = 132MHZ
while (CCM->CDHIPR & (1 << 1)); // 等待 AHB_PODF 握手完成
IOMUXC_GPR->GPR1 |= (1 << 26); // 开启 AHB_ROOT_CLK 时钟
修改 AHB_PODF
时会发生握手,根据 NXP
官方手册,在修改不带握手机制的分频器时,才需要事先关闭时钟。但是这里还是为了保险,先关闭时钟。
NXP
官方文档的说明。
还有就是修改 IPG_CLK_ROOT
和 PERCLK_CLK_ROOT
时钟分频器时,应该是要事先关闭输出时钟的,但是没找到哪个寄存器关闭,看看有没有大佬告知一下。