mazhenguo 发表于 2026-4-15 10:51:06

SPI使用HPLL2 时钟问题,如果是普遍情况希望改进,或在规格书中说明一下

SPI使用HPLL2 时钟,经过测试发现
HPLL1不启用
HPLL2   启用
SPI时钟没有输出
HPLL1   启用
HPLL2   启用
SPI时钟有输出
SPI使用HPLL1 时钟,
HPLL1   启用
SPI时钟有输出

特别注意如果使用HPLL1后,不断电动情况下
再次启用HPLL2   关闭HPLL1后编译下载,程序
可以正常运行,但是重新上电后,就没有输出了


使用的测试函数如下

////////////////////////////////////////
// 时钟初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void CLK_Init(void)
{
    CLK_I2S1CLK_Divider(1);             //设置I2S1时钟预分频系数
    CLK_I2S2CLK_Divider(1);             //设置I2S2时钟预分频系数
    CLK_SPI1CLK_Divider(1);             //设置SPI1时钟预分频系数
    CLK_SPI2CLK_Divider(6);             //设置SPI2时钟预分频系数
    CLK_SPI3CLK_Divider(40);            //设置SPI3时钟预分频系数
    CLK_PWMACLK_Divider(1);             //设置PWMA时钟预分频系数
    CLK_PWMBCLK_Divider(1);             //设置PWMB时钟预分频系数
    CLK_PWMCCLK_Divider(1);             //设置PWMC时钟预分频系数
    CLK_PWMDCLK_Divider(1);             //设置PWMD时钟预分频系数
    CLK_PWMECLK_Divider(1);             //设置PWME时钟预分频系数
    CLK_PWMFCLK_Divider(1);             //设置PWMF时钟预分频系数
    CLK_TFPUCLK_Divider(1);             //设置TFPU时钟预分频系数

    CLK_SYSCLK_Divider(10);             //切换主时钟前先将系统时钟降频

    HIRC_48M();                         //选择内部预置的频率

    CLK_MCLK_HIRC();                  //选择内部高精度HIRC作为主时钟
    CLK_MCLK2_BYPASS();               //旁路MCLK2,直接使用MCLK选择

//    CLK_HPLL1_BASECLK();                //选择内部基本时钟BASECLK作为HPLL1输入时钟
//    CLK_HPLL1_PreDivider(8);            //设置HPLL1的输入时钟预分频系数(分频后的频率必须为6MHz左右)
//    CLK_HPLL1_Lock312MHz();             //选择HPLL1的锁频目标频率
//    CLK_HPLL1_Enable();               //启动HPLL1

    CLK_HPLL2_BASECLK();                //选择内部基本时钟BASECLK作为HPLL2输入时钟
    CLK_HPLL2_PreDivider(8);            //设置HPLL2的输入时钟预分频系数(分频后的频率必须为6MHz左右)
    CLK_HPLL2_Lock312MHz();             //选择HPLL2的锁频目标频率
    CLK_HPLL2_Enable();               //启动HPLL2
    delay_ms(1);                        //等待PLL锁频

    CLK_SYSCLK_Divider(1);            //设置系统时钟分频系数

//    CLK_HSI2SCK_HPLL1D2();            //选择HPLL1的输出2分频时钟作为高速I2S时钟源
    CLK_HSIOCK_HPLL2D2();               //选择HPLL2的输出2分频时钟作为高速外设时钟源
               
//    CLK_HSIOCK_HPLL1();               //选择HPLL1的输出时钟作为高速外设时钟源

    //<<AICUBE_USER_CLOCK_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
    //<<AICUBE_USER_CLOCK_INITIAL_END>>
}

乘风飞扬 发表于 2026-4-15 15:11:04

高速外设默认使用HPLL时钟,只使能HPLL2时钟的话,切换到HPLL2前要先使能HPLL,切换完再关闭HPLL。
可参考实验箱例程包里面的PLL时钟配置过程:
    WTST = 2;         //通过WTST增加等待时钟控制Flash读取速度在33MHz以内, 主时钟:480MHz/2/3=80MHz, 读Flash速度:80MHz/(1+2)=26.7MHz

    HPLLCR |= 0x80;   //使能HPLL(高速外设默认使用HPLL时钟,切换到HPLL2前要先使能HPLL,切换完再关闭HPLL)

                        //首先需要将HIRC主频调节到48MHz
    HPLL2CR &= ~0x10;   //选择HPLL2输入时钟源为HIRC
//    HPLL2CR |= 0x10;    //选择HPLL2输入时钟源为IRCM
    HPLL2PDIV = 8;      //设置HPLL2输入时钟预分频为8(HPLL输入频率必须为6MHz)
//    HPLL2CR |= 0x00;    //HPLL2=6MHz*52=312MHz
//    HPLL2CR |= 0x01;    //HPLL2=6MHz*54=324MHz
//    HPLL2CR |= 0x02;    //HPLL2=6MHz*56=336MHz
//    HPLL2CR |= 0x03;    //HPLL2=6MHz*58=348MHz
//    HPLL2CR |= 0x04;    //HPLL2=6MHz*60=360MHz
//    HPLL2CR |= 0x05;    //HPLL2=6MHz*62=372MHz
//    HPLL2CR |= 0x06;    //HPLL2=6MHz*64=384MHz
//    HPLL2CR |= 0x07;    //HPLL2=6MHz*66=396MHz
//    HPLL2CR |= 0x08;    //HPLL2=6MHz*68=408MHz
//    HPLL2CR |= 0x09;    //HPLL2=6MHz*70=420MHz
//    HPLL2CR |= 0x0a;    //HPLL2=6MHz*72=432MHz
//    HPLL2CR |= 0x0b;    //HPLL2=6MHz*74=444MHz
//    HPLL2CR |= 0x0c;    //HPLL2=6MHz*76=456MHz
//    HPLL2CR |= 0x0d;    //HPLL2=6MHz*78=468MHz
      HPLL2CR |= 0x0e;    //HPLL2=6MHz*80=480MHz
//    HPLL2CR |= 0x0f;    //HPLL2=6MHz*82=492MHz
    HPLL2CR |= 0x20;    //高速外设时钟选择 HPLL2/2
    HPLL2CR |= 0x80;    //使能HPLL2

    HPLLCR &= ~0x80;    //关闭HPLL(高速外设默认使用HPLL时钟,切换到HPLL2前要先使能HPLL,切换完再关闭HPLL)
   
    CLKDIV = 3;         //系统时钟 = 主时钟源/2 = HPLL2/2/3 = 80MHz
    CLKSEL = 0x08;      //选择HPLL2/2作为主时钟源
页: [1]
查看完整版本: SPI使用HPLL2 时钟问题,如果是普遍情况希望改进,或在规格书中说明一下