首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提高STM32F401不工作时钟速度的代码

提高STM32F401不工作时钟速度的代码
EN

Stack Overflow用户
提问于 2022-04-26 08:51:51
回答 1查看 307关注 0票数 0

我试着用锁相环将STM32F401的时钟速度提高到84 the。我试着争取登录时间。但代码不起作用。有人能检查一下需要做什么吗?外部晶体是功能性的,因为我使用HAL库检查了它。

我尝试不使用HAL的原因是,我看到几个文档说HAL消耗了太多内存,最好避免它。

代码语言:javascript
复制
void Enable_PLL_F401(void)
{
    //Enable The HSE
    RCC->CR |= RCC_CR_HSEON;
    //Wait Until HSE Stabilizes
    //Remove While Loop; If the HSE isn't stabilized, code will stuck
    while(!(RCC->CR & RCC_CR_HSERDY))
        ;
    /* Activate Prefetch Buffer*/
    /*        Optional         */
    
    
    //Configure the PLL registers
    RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC;  //PLL Source HSE
    RCC->PLLCFGR &=~ (RCC_PLLCFGR_PLLM); //Clearing PLLM values
    RCC->PLLCFGR |= (RCC_PLLCFGR_PLLM_0 | RCC_PLLCFGR_PLLM_3 | RCC_PLLCFGR_PLLM_4);  //Divided by 25
    RCC->PLLCFGR &=~ RCC_PLLCFGR_PLLN;   //Clearing PLLM values
    RCC->PLLCFGR |= (RCC_PLLCFGR_PLLN_4|RCC_PLLCFGR_PLLN_6|RCC_PLLCFGR_PLLN_8);      //Multiplied by 336
    RCC->PLLCFGR &=~ RCC_PLLCFGR_PLLP;   //Clearing PLLP values
    RCC->PLLCFGR |= RCC_PLLCFGR_PLLP_0;  //Divided by 4
    RCC->PLLCFGR &=~ RCC_PLLCFGR_PLLQ;   //Clearing PLLP values
    RCC->PLLCFGR |= RCC_PLLCFGR_PLLQ_2;  //Divided by 4 [USB-OTG Clock]
    
    RCC->CFGR &=~ RCC_CFGR_HPRE;         //System Clock Not Divided [AHB Prescalar]
    RCC->CFGR &=~ RCC_CFGR_PPRE1_DIV16;  //Clearing PPRE1 values
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
    RCC->CFGR &=~ RCC_CFGR_PPRE2_DIV16;  //Clearing PPRE2 Values
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;    //AHB not divided [APB2 Prescalar]
    
    RCC->CR |= RCC_CR_PLLON;
    //Wait Until HSE Stabilizes
    //Remove While Loop; If the HSE isn't stabilized, code will stuck
    while(!(RCC->CR & RCC_CR_PLLRDY))
        ;
    
    RCC->CFGR &=~ RCC_CFGR_SW;
    RCC->CFGR |= RCC_CFGR_SW_PLL;
    
    while(!(RCC->CFGR & RCC_CFGR_SWS_PLL))
        ;
    
    //SystemInit();
    SystemCoreClockUpdate();
}

这是CubeMX中的时钟配置:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-07 10:21:31

尽管这个问题仍然缺少一些信息,但让我尝试给你一些提示:

写入单片机寄存器

首先,用许多小步骤写入PLLCFGR寄存器通常不是一条路。请参见代码的以下部分:

代码语言:javascript
复制
//Configure the PLL registers
RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC;  //PLL Source HSE
RCC->PLLCFGR &=~ (RCC_PLLCFGR_PLLM); //Clearing PLLM values
RCC->PLLCFGR |= (RCC_PLLCFGR_PLLM_0 | RCC_PLLCFGR_PLLM_3 | RCC_PLLCFGR_PLLM_4);  //Divided by 25
RCC->PLLCFGR &=~ RCC_PLLCFGR_PLLN;   //Clearing PLLM values
RCC->PLLCFGR |= (RCC_PLLCFGR_PLLN_4|RCC_PLLCFGR_PLLN_6|RCC_PLLCFGR_PLLN_8);      //Multiplied by 336
RCC->PLLCFGR &=~ RCC_PLLCFGR_PLLP;   //Clearing PLLP values
RCC->PLLCFGR |= RCC_PLLCFGR_PLLP_0;  //Divided by 4
RCC->PLLCFGR &=~ RCC_PLLCFGR_PLLQ;   //Clearing PLLP values
RCC->PLLCFGR |= RCC_PLLCFGR_PLLQ_2;  //Divided by 4 [USB-OTG Clock]

这将对同一个寄存器执行9次写操作。在第一个写,您选择HSE振荡器时钟。在第二次写入中,您将清除主锁相环(PLLM)的除法因子。但是,值0是无效的值。这可能已经引起了问题(我不认为这种情况下的行为是指定的,所以我们只能猜测会发生什么)。

通过首先计算正确的值,然后在这样的一个操作中将其写入寄存器,可以很容易地避免这种情况:

代码语言:javascript
复制
uint32_t reg = RCC->PLLCFGR;
//Configure the PLL registers
reg |= RCC_PLLCFGR_PLLSRC;  //PLL Source HSE
reg &=~ (RCC_PLLCFGR_PLLM); //Clearing PLLM values
reg |= (RCC_PLLCFGR_PLLM_0 | RCC_PLLCFGR_PLLM_3 | RCC_PLLCFGR_PLLM_4);  //Divided by 25
reg &=~ RCC_PLLCFGR_PLLN;   //Clearing PLLM values
reg |= (RCC_PLLCFGR_PLLN_4|RCC_PLLCFGR_PLLN_6|RCC_PLLCFGR_PLLN_8);      //Multiplied by 336
reg &=~ RCC_PLLCFGR_PLLP;   //Clearing PLLP values
reg |= RCC_PLLCFGR_PLLP_0;  //Divided by 4
reg &=~ RCC_PLLCFGR_PLLQ;   //Clearing PLLP values
reg |= RCC_PLLCFGR_PLLQ_2;  //Divided by 4 [USB-OTG Clock]
RCC->PLLCFGR = reg;

这同样适用于代码中的其他寄存器。

动态重新配置时钟

我不太清楚你是想动态地提高MCU的时钟速度(所以当它已经在运行时)还是静态地(因此改变初始配置)。

如果您想动态地改变时钟速度,还需要考虑以下几点:

  • 一旦启用PLL,主PLL配置就无法更改。所以,如果你想改变时钟的速度,你必须首先禁用它。
  • 您必须确保在任何时候至少有一个有效的系统时钟。如果您正在重新配置主PLL,则必须临时切换到内部时钟(HSI)。

由于我不知道您的启动时钟配置,我不能深入到更多的细节,但我希望这将提供足够的信息。

闪存等待状态

正如old_timer和Tagli提到的,您可能还需要调整flash等待状态。这在STM32F401参考手册(RM0368)的3.4.1节“CPU时钟频率和闪存读取时间之间的关系”中进行了描述(修订版5)。所需值取决于您的电源电压和CPU时钟频率。

稳压器电压

为了能够在MHz上实现84 STM32F4,必须将调节器电压缩放输出设置为2( PWR_CR寄存器中的VOS=2)。这是重置后的默认设置,但如果初始配置不同,则可能必须再次设置。

注意:关于你的声明“我尝试没有HAL的原因是我看到几个文件说HAL消耗了太多的内存,最好避免它。”这句话有一点是正确的,但这并不是你应该遵循的一般规则。对于像时钟配置这样的低级别的东西,HAL代码是非常基本的,不会花费那么多内存。考虑到它的复杂性,我不会去重写它,除非我真的需要保存每一个字节的内存。高级HAL函数(例如UART或I2C )相当大,因为它们试图涵盖许多用例,而且只编写所需的代码可能会节省相当大的内存。不过,我还是会从HAL函数开始,只在需要时进行优化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72011047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档