0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CPU时钟调高时出现异常的案例及解决方案分享

茶话MCU 2017-12-18 14:00 次阅读

近日某论坛STM32用户反馈,使用STM32F103内部时钟,把系统时钟配置成64MHz单片机就不跑了,配置成36MHz程序就正常妥妥的,频率稍高点就容易导致死机。他贴出的代码如下:

void RCC_Configuration(void)

{

RCC_DeInit();//将外设 RCC寄存器重设为缺省值

RCC_HSICmd(ENABLE);//使能HSI

while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);//等待HSI使能成功

//FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

//FLASH_SetLatency(FLASH_Latency_2);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div2);

RCC_PCLK2Config(RCC_HCLK_Div1);

//设置 PLL 时钟源及倍频系数

RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);

结合他的问题描述及他贴出来的代码,大致可以判断出很可能是因为他屏蔽了指令预取和flash读取等待延迟的参数配置而导致的异常。即上面两条红色标注出来的代码。

后来我明确地提醒他这点后,他似乎并没及时反应过来,还折腾了几下才开启了上述配置,问题最终得以解决。

其实,关于这个问题经常有人遇到,尤其是那些基于STM32标准固件库进行开发或自行编程时的新手更容易碰到这个问题。主要原因是他们对上述两行代码的功能不了解,导致有意或无意的将库例程中相关代码屏蔽掉无视掉不做配置、或者配置不正确。

这里将这个问题再次分享出来,对上面两行代码简单做些解释。希望更多人对此有所知晓,少在这个地方走弯路。

这句FLASH_PrefetchBufferCmd();用来作为flash指令预取功能的使能或禁用。

现有STM32各个系列都是基于ARM cortexM内核的微处理器,采用多级流水线的哈佛结构,即一条指令的执行分割为几个阶段,如取指、译码、执行等,使得当前指令的取指操作完成后就可以开始后续指令的取指、译码等操作,程序指令就这样像流水一样执行下去,大大提高了指令的执行效率。

具体到STM32各系列单片机,这个指令预取功能的开启或关闭可以软件配置,一般配置为开启。要注意的是,芯片复位后不同的系列该功能有的默认为开启有的则默认为关闭。比方STM32F1系列的flash指令预取功能就是默认打开的,当然你也可以关闭。其中,明确要求打开的情景就是当那个AHB时钟预分频系数不等于1时。

CPU时钟调高时出现异常的案例及解决方案分享

再比如STM32F4系列,它的指令预取功能在芯片复位后是默认关闭的,你可以自行打开。但明确要求关闭的场景就是芯片的供电电压低于2.1V时。

其实,STM32F4的预取功能与STM32F1不尽一样,STM32F4、STM32F2、STM32L4、STM32F7等系列芯片使用了ST的专利技术ART存储加速器【Adaptive real-time memory accelerator】。该加速器使用指令预取队列和分支跳转缓存技术,从而提高 Flash 程序代码执行速度,使得CPU即使在其最高主频下也能完美实现0等待执行flash程序指令。

上面大致讲了指令预取功能,预取主要是为了实现指令读取和执行的高效性。具体细节请参考相关技术手册。我们知道CPU的运行速度可调,可以很快,通常使用高速总线访问FLASH接口控制器,FLASH控制器收到来自CPU的取指指令后然后去读取相应地址的指令或数据。Flash控制器自身的读取速度相比CPU的高速请求来说可能会出现滞后,往往需要CPU做相应的延时等待。为了让CPU准确及时读取 Flash 数据,我们须根据 CPU 时钟频率、FLASH控制器自身特性以及器件供电情况在Flash存取控制寄存器(FLASH_ACR)中正确地编程等待周期数(LATENCY),类似上面提到的第二句代码:

FLASH_SetLatency(FLASH_Latency_n);

这里的等待周期数视不同的STM32系列也各有差异,不妨以STM32F4为例:

CPU时钟调高时出现异常的案例及解决方案分享

下面是个关于STM32F4系列部分产品线的LATENCY设置的表格。从表格中可以看出LATENCY参数的设置与CPU的时钟、电源电压都有关系。另外,当电源电压在2.1V以下上要关闭预取功能。

CPU时钟调高时出现异常的案例及解决方案分享

在设置上面的等待周期参数时,选择合适的就好。不难理解,设置太大了影响CPU性能的充分发挥,太小了容易导致异常。

具体回到开头的案例,它出现死机问题,极可能是因为没有合理配置等待周期参数导致异常,因为它屏蔽了参考例程中那两句配置代码,即使用其默认功能,对于STM32F1,指令预取功能默认为开启。而STM32F1系列芯片的latency默认值即为0,无等待。这样的话,当他把时钟调高到一定程度时出现死机就不难理解了。

另外,当他反馈时钟调高产生异常时,我还给他提醒了注意检查VDDA的电源情况。我碰到有人遇到因VDDA没接好使得PLL不正常的情况。我们知道,对于STM32芯片,调高其工作时钟,往往借助于锁相环。而PLL的供电来自VDDA,如果PLL没有被正常供电,也是个非常隐蔽的麻烦。曾经有个客户为此折腾好久,才愿沉下心来检查其“坏品”的电源,结果发现有个VDDA脚虚焊。一直以芯片低频没问题,频率高了就异常为由怀疑芯片品质问题而耽误时间。

CPU时钟调高时出现异常的案例及解决方案分享

最后给点建议,做STM32开发的话,尤其是新手,如果参照ST的官方例程的话,有些配置在没看懂的情况下不要轻易屏蔽或修改。我碰到多个类似本案随意屏蔽例程中的初始化配置代码或断言代码出现异常,自己又找不到方向的。另外,尽可能使用ST官方的stm32cubeMx图形配置工具做基本的配置,通过它来生成初始化配置文件,这样方便省事很多。当然,即使使用STM32CUBEMX配置也不是万能的。比方:曾经有人使用STM32F0开发产品,用CUBEMX配置初始化文件,刚开始配置时时钟选择得比较低, STM32CubeMx自然根据他选择的时钟做了相关参数配置。后来他自己在用户代码里手动调高了时钟,而不知相应调整跟FLASH读取等待有关的参数,也是发生跟本案同样的情况。所以呢,如果能对原理有更多更深的把握那是再好不过了。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32F103
    +关注

    关注

    33

    文章

    474

    浏览量

    62569
  • cpu时钟
    +关注

    关注

    0

    文章

    1

    浏览量

    1422

原文标题:CPU时钟调高时出现异常的案例分享

文章出处:【微信号:stmcu832,微信公众号:茶话MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    电机转速调高出现over current问题怎么解决?

    请教网友: 电机低转速运行正常,但是当转速调高出现over current问题?可能是什么原因呢? 示波器是uvw的控制pwm输出。调试了好多参数组合都不能满足提高转速的目的。请教各位前辈,谢谢!
    发表于 04-24 06:05

    利用Motor Profiler测试电机参数时,老是出现异常的原因?

    大家好,我在利用Motor Profiler测试电机参数时,老是出现异常
    发表于 04-03 06:08

    STM32F407ZG MCU控制器偶尔会出现异常复位,为什么?

    我这边用了STM32F407ZG MCU, 发现控制器偶尔会出现异常复位。 程序使用了独立看门狗,没有使用窗口看门狗。通过监控RCC->CSR, 发现异常复位时以下位置1: .位29
    发表于 04-01 07:13

    STM32定时器DMA输出单通道和双通道输出切换出现异常的原因?

    STM32定时器DMA输出单通道和双通道输出切换出现异常
    发表于 03-26 06:44

    CAN模块RxBuffer接收异常要怎么处理呢?

    你好,我在测试CYT2B75功能的时候发现当其他中断占用过多时间的时候,CAN模块就会出现异常,设置在RxBuffer Idx 大的CAN消息无法接收到,出现异常后就算调用
    发表于 02-01 08:10

    使用SC584外扩DDR3,程序均在adi_gic_GetIntSecurityStatus函数出现异常的原因?

    ,程序均在adi_gic_GetIntSecurityStatus函数出现异常,请帮助之处引起该问题的原因。 谢谢!
    发表于 01-12 08:11

    时钟域的解决方案

    在很久之前便陆续谈过亚稳态,FIFO,复位的设计。本次亦安做一个简单的总结,从宏观上给大家展示跨时钟域的解决方案
    的头像 发表于 01-08 09:42 373次阅读
    跨<b class='flag-5'>时钟</b>域的<b class='flag-5'>解决方案</b>

    ADIS16445正常使用一段时间后出现异常有什么解决办法?

    ADIS16445正常使用一段时间后出现异常。目前上电后使用示波器测量中断信号产生线DIO1时一直是处于高电平,读产品ID可以正确读到,然而发0x3E00获取陀螺仪和加速度计的组数据均为0不响应
    发表于 12-28 07:22

    使用ADXL355发现数据在工作一段时间后出现异常的原因?

    近期在使用ADXL355发现数据在工作一段时间后出现异常。可确保通信正常,芯片ID检查通过。异常表现为: 1.出现异常数据保持不动,或周期跳动; 2.上电不可恢复,需要敲击恢复正常; 3.
    发表于 12-27 08:09

    使用AD7656进行四通道采样,将四通道输入接地后采样值出现异常的原因?

    求助:使用AD7656进行四通道采样,将四通道输入接地后采样发现采样值出现异常,具体表现(见图1)为: 1. 第一通道采样正确,跳动量不超过10; 2.第2,3,4通道采样出现跳动,跳动量似乎每次为为255。 求助各位大神帮忙分析一下什么原因? 原理图见图2 图
    发表于 12-18 06:10

    sigmaStudio for SHARC在ADSP-21489编译下,Reverb模块出现异常,加载后出错怎么解决?

    sigma Studio for SHARC 在ADSP-21489编译下,Reverb,模块出现异常,加载后出错。 不知道是不是编译资源超过芯片所用资源? 加载到ADSP-21489_EZ-Board开发板后,没有声音。把Reverb模块去掉后,就正常有声音。
    发表于 11-28 07:16

    开关PLL有极小概率造成USB 48MHz时钟异常丢失

    在使用USB时,需要给USB控制器提供48MHz时钟用于USB的总线采样,在选择PLL分频作为USB 48MHz时钟源时,开关PLL的过程中,USB分频器有极小概率出现异常,USB48MHz
    发表于 10-23 08:25

    Python异常处理和单元测试简介

    程序越复杂,出现异常的概率越大,如何在程序崩溃之前,捕捉异常,预判异常?项目越大,需要测试的内容越多,如何快速有效地测试?
    发表于 09-04 16:27 228次阅读
    Python<b class='flag-5'>异常</b>处理和单元测试简介

    NuEclipse调试OpenOCD failed出现异常怎么解决?

    最近学习NuEclipse,调试NuTiny-EVB-Mini51板,编译正常,但调试出现异常
    发表于 06-20 08:08

    连接到WiFi时不断出现异常的原因?怎么解决?

    () { Serial.begin(115200); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); } void loop() { } 我将代码缩小到此以重现该问题。问题是不断出现异常
    发表于 05-04 08:40