F407延时时间不对

之前用F103,后来有了点知识储备之后选择上了F407,体验一下更高级的性能。

一开始就蒙圈了,延时总是不对,闪烁根本驱动不起来,后来控制变量法发现是没有初始化时钟,Delay_Init(168),因为之前用F103的时候开始不用初始化时钟,直接写主函数就行了,在F407的时候结果就要初始化时钟,光这个问题就折腾了我一个星期,后来结局了之后总归能闪烁了,但是延时时间怎么都不对。

用的正点原子所提供的工程模板,自己编写的主函数,功能是两个灯一起闪烁,延时500ms。我自己写的工程,500ms有将近1.5s,但是用正点原子提供的实例却没有问题。我对照了时钟配置,全是一模一样的,根本就不会不同,因为我用的就是他们所提供的模板。

左边是例程,右边是我自己写的。

img

时钟配置发过来看一下,PLL的配置和例程是否完全一致?HSE_VALUE是不是设置了正确的外部晶振值?外部晶振频率和例程用的板子的晶振是不是一样?

该回答引用GPTᴼᴾᴱᴺᴬᴵ
您好,F103和F407在时钟初始化方面是不同的,因为它们使用的是不同的芯片。F103默认时钟频率为72MHz,但是F407默认时钟频率为25MHz,如果您没有进行时钟初始化,则无法获得正确的延迟时间。在F407上,您需要首先启用HSI时钟源,然后设置PLL倍频因子和系统时钟分频因子以达到所需的时钟频率。另外,F407和F103在延迟时间方面可能有所不同,因为它们具有不同的时钟速度和执行指令的速度。在使用延迟函数时,请确保您的延迟时间是按照您的时钟频率和执行指令速度计算出来的。

在STM32F407中使用延时函数需要注意以下几个方面:

  1. 时钟配置:在使用延时函数前需要初始化系统时钟,否则延时函数无法正常工作。在使用STM32CubeMX生成工程时,系统时钟的初始化代码已经自动生成,如果你是手动配置系统时钟的话,需要保证时钟配置正确。

  2. 延时函数的实现:在STM32F407中,延时函数可以使用SysTick定时器来实现。在使用SysTick定时器前需要先初始化SysTick,配置SysTick时钟为HCLK/8,并使能SysTick中断。具体实现可以参考以下代码:

void delay_init(uint8_t SYSCLK)
{
    SysTick->CTRL &= ~(1 << 2);  // 关闭SysTick定时器
    SysTick->CTRL |= 1 << 1;     // 配置SysTick时钟为HCLK/8
    SysTick->LOAD = SYSCLK / 8 - 1;  // 设置重载值
    SysTick->VAL = 0;            // 清零计数器
    SysTick->CTRL |= 1 << 0;     // 使能SysTick定时器
}

void delay_ms(uint16_t nms)
{
    uint32_t ticks;
    ticks = nms * SystemCoreClock / 8000;  // 计算延时的tick数
    SysTick->CTRL &= ~(1 << 0);    // 关闭SysTick定时器
    SysTick->LOAD = ticks;         // 设置重载值
    SysTick->VAL = 0;              // 清零计数器
    SysTick->CTRL |= 1 << 0;       // 使能SysTick定时器
    while (!(SysTick->CTRL & (1 << 16))); // 等待延时完成
}

3.时钟频率的配置:在使用延时函数时需要保证系统时钟的频率已经正确配置,否则计算延时时间会出现错误。在F407中时钟频率为168MHz,因此在计算延时时间时需要使用以下公式:

延时时间(ms)= 延时tick数 * 1000 / SysTick时钟频率

根据以上的几个方面进行检查和调整,如果还有问题可以通过调试程序、查看寄存器值等方式进一步排查问题。
·
补充:
在您提供的两个代码中,似乎没有显示您如何计算延迟时间的部分,因此我无法确定您的延迟时间是否正确。但是,您可以尝试以下步骤来解决问题:

  1. 确保您已正确初始化F407的时钟。
  2. 确保您的延迟时间计算正确。例如,如果您的时钟频率为168MHz,并且您正在使用SysTick延迟函数,则500ms的延迟时间应为84,000,000个时钟周期。
  3. 如果您使用的是其他类型的延迟函数,请检查其文档以了解正确的使用方法。
  4. 如果以上步骤都没有解决您的问题,请尝试使用调试器单步调试程序以查看延迟时间是否按预期执行。

希望这可以帮助您解决问题!