最近买了一款stm32f407zgt6的核心板,毫不犹豫地写了一个用定时器点亮led灯的程序(由于程序比较简单就不贴上来了)。在进行1秒闪烁功能实现时,明显发现了led的闪烁时间不对,刚开始是拿手机进行简单的计时,结果显示的是大约3秒的延时(测了10秒亮了两次),在仔细检查代码后,确定不是代码问题(因为代码是用的野火的示例代码)
SystemCoreClock是系统预设的系统时钟,在System_stm32f4xx.c文件中查的,f407对应的系统时钟是168mhz
由SysTick_Init()函数,通过计算处理肯定能得到精确的定时,后通过定时器控制GPIO引脚连接至示波器检测,在高电平延时1ms的情况下,测得实际值为3.1ms。再次检查程序,确定没有问题后。意识到可能是系统时钟配置的问题。期间使用了网上推荐的获得系统时钟频率的函数来检测的方法,但是没有实际进展,这里略过。按着思路,我找到了时钟配置的原理图由上图,我们使用的是systick,其时钟源是HSE。也就是说systick的频率 f=(HSE/M)*N/P 由本帖第三幅图上可得参数
M = 25 N=336 P=2 在System_stm32f4xx.c文件中,找到了如下配置
这下确认没有问题了,把频率参数 168000000hz代入公式反算,得到HSE=25000000,也就是说hse的输入频率应该是25Mhz,这明显符合图一上面的参数。由此确定,该问题并不是程序上的问题。于是问题集中到硬件上,那可能性就比较多了,先从时钟源入手,上面的系统时钟原理图可以看出,hse的时钟源由OSC_OUT与OSC_IN接入,找到核心板电路图,如图
本来是按着25MHZ的晶振去找,怎么都找不到,接着查引脚,找到了这个8MHZ的外部晶振,问题根源终于找到了,这块板子的时钟源用的是8MHZ,但是系统配置里面默认是按照25MHZ的,将HSE=8MHZ带入计算公式,得到Systick=53760000HZ,大约是理想值的三分之一,到此终于确定了问题所在,为了后面工程的良好实施,系统频率还是用规定的168MHZ,为好。接着修改就比较简单了。
由公式反算,如果M=8的话,能得到理想频率(为什么不是其他参数,请参考一下中文手册,其他参数是有范围的)
接下来是在系统配置里修改M参数,先将system_stm32f4xx.c文件的只读属性去掉(找到该文件,右键属性去掉只读),在kile5中重新打开该文件,将代码翻到371行
将 25 改为 8,保存文件。将文件的只读属性加上,就可以完工了。到此时钟终于正常了。事实证明这里不改的话,后面的串口通信,spi,i2c问题多多,我也是被折磨一阵后回来写这个的。
最后附上我的核心板实物图
当然,这个问题还有其他的解决办法,欢迎大家交流讨论,可以邮件 1452912499@qq.com联系讨论。