STM32F072C8配置晶振时出现的一起诡异HardFault

2019-12-12 18:21发布

本帖最后由 fnems 于 2019-3-12 22:19 编辑

事情是这样的,一个测试板上STM32F072用了16MHz的3225贴片晶振。使用16MHz是因为便宜,3225晶振尺寸比较小,小尺寸晶振难以做到低频率(固有频率与外形尺寸成反比)。

072的最高工作频率是48MHz。虽然可以将16MHz三倍频得到,但是我打算先将16MHz晶振频率2分频到8MHz,再6倍频到48MHz。

查看f0xx的TRM手册,时钟树原理图 Figure 12. Clock tree (STM32F04x, STM32F07x and STM32F09x devices)里面,PLL的预分频需要设置PREDIV,又查到PREDIV位于RCC_CFGR2寄存器。

我将system_stm32f0xx.c文件中设置时钟频率的SetSysClock函数改写,在
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6);
之前加入一行:
RCC->CFGR2 = RCC_CFGR2_PREDIV1_DIV2;

这样编译出来的程序,在执行完SetSysClock函数后不会立即出错,而是跑进main之后执行数十条指令,之后会进入Hardfault,而且进入fault的位置还不固定,有时早一点有时晚一点。

由于手册中也说,PREDIV[3:0],  Note: Bit 0 is the same bit as bit 17 in Clock configuration register (RCC_CFGR), so
modifying bit 17 Clock configuration register (RCC_CFGR) also modifies bit 0 in Clock
configuration register 2 (RCC_CFGR2) (for compatibility with other STM32 products)
如果我把system_stm32f0xx.c中的
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6);
改为
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2| RCC_CFGR_PLLMULL6);
且不修改RCC->CFGR2寄存器,那么就能得到预期的48MHz系统时钟。

是不是很奇怪… 修改RCC->CFGR2会进入Hardfault。
由于手头暂时只有一块使用16MHz晶振的测试板,没法验证本帖故障是否具有普遍性。还请有兴趣的大侠测试一下把结果贴出来。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
wajlh
1楼-- · 2019-12-12 23:20
用cubemx生成一个工程再试试
fnems
2楼-- · 2019-12-13 01:55
wajlh 发表于 2019-3-12 22:18
用cubemx生成一个工程再试试

感谢关注和提示。

CubeMX生成的工程里,同时修改了CFGR2和CFGR。
相关代码:
#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSOURCE__ , __PREDIV__, __PLLMUL__)
                  do {
                    MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PREDIV, (__PREDIV__));
                    MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC, (uint32_t)((__PLLMUL__)|(__RCC_PLLSOURCE__)));
                  } while(0U)

该宏位于STM32F0xx_HAL_DriverIncstm32f0xx_hal_rcc.h。

代码调用树:
main --> SystemClock_Config --> HAL_RCC_OscConfig --> __HAL_RCC_PLL_CONFIG
wye11083
3楼-- · 2019-12-13 04:02
我记得很久以前就有人提到过flash的读延时,你要是不配好读延时,铁定会bug,因为cpu从flash里面读到的数据是错的。
wajlh
4楼-- · 2019-12-13 05:34
fnems 发表于 2019-3-12 22:29
感谢关注和提示。

CubeMX生成的工程里,同时修改了CFGR2和CFGR。

问题是cubemx的代码运行正常么?如果正常,你就按照cubemx来做就好了,如果不正常,八成是晶振部分有问题。用cubemx生成一个内部RC的工程再跑,基本上就可以确定出问题出在哪里了
tomzbj
5楼-- · 2019-12-13 08:40
 精彩回答 2  元偷偷看……

一周热门 更多>