本帖最后由 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晶振的测试板,没法验证本帖故障是否具有普遍性。还请有兴趣的大侠测试一下把结果贴出来。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
感谢关注和提示。
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
问题是cubemx的代码运行正常么?如果正常,你就按照cubemx来做就好了,如果不正常,八成是晶振部分有问题。用cubemx生成一个内部RC的工程再跑,基本上就可以确定出问题出在哪里了
一周热门 更多>