我的项目已经开始遇到一个问题,其中SysTick率通常是,但并不总是设置得太快。我没有改变相关的代码,它似乎与温度有关。
我在Visual Studio Community 2015上使用STM32F072B-DISCOVERY板和VisualGDB。
我的初始化代码包括以下功能:
void Setup_Init_Clocks()
{
// Set up 48 MHz Core Clock using HSI (8Mhz) with PLL x 6
RCC_PLLConfig(RCC_PLLSource_HSI, RCC_PLLMul_6);
RCC_PLLCmd(ENABLE);
// Wait for PLLRDY after enabling PLL.
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) != SET)
{ }
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select the PLL as clock source.
SystemCoreClockUpdate();
}
RCC_SYSCLKConfig()
状态的注释"如果选择了尚未就绪的时钟源,则在时钟源就绪时将进行切换。"检查PLLRDY RCC标志应该识别这种情况,以便立即发生时钟变化,以便立即设置时钟。
SystemCoreClockUpdate()
来自标准STM32库(在文件system_stm32f0xx.c中)并重新计算稍后用于设置SysTick的值:
void SystemCoreClockUpdate (void)
{
uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case 0x00: /* HSI used as system clock */
SystemCoreClock = HSI_VALUE;
break;
case 0x04: /* HSE used as system clock */
SystemCoreClock = HSE_VALUE;
break;
case 0x08: /* PLL used as system clock */
/* Get PLL clock source and multiplication factor ----------------------*/
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
pllmull = ( pllmull >> 18) + 2;
if (pllsource == 0x00)
{
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
}
else
{
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
/* HSE oscillator clock selected as PREDIV1 clock entry */
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
}
break;
default: /* HSI used as system clock */
SystemCoreClock = HSI_VALUE;
break;
}
/* Compute HCLK clock frequency ----------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
/* HCLK clock frequency */
SystemCoreClock >>= tmp;
}
在调试器中,我可以看到失败的地方:tmp = RCC->CFGR & RCC_CFGR_SWS;
,导致选择了错误的大小写。
这在反汇编程序中看起来相对简单:
237: tmp = RCC->CFGR & RCC_CFGR_SWS;
0x08003262 2A 4B ldr r3, [pc, #168] ; (0x800330c SystemCoreClockUpdate+192>)
0x08003264 5B 68 ldr r3, [r3, #4]
0x08003266 0C 22 movs r2, #12
0x08003268 13 40 ands r3, r2
0x0800326a FB 60 str r3, [r7, #12]
RCC CFGR寄存器的值为0x0010800a。 RCC_CFGR_SWS
掩码是0x0000000c。此的结果应 tmp
分配0x08,选择PLL情况,SystemCoreClock
设置为48000000。
1)如果我在此语句之前或之前设置断点,并逐步执行它,并且tmp
分配了0x08,并且时钟设置正确。
2)如果我之后立即在switch
语句中设置了断点,它通常会失败。 tmp
被分配0x0010800a,就像跳过了ands r3, r2
指令一样!这导致default
情况被执行,而SystemCoreClock被设置为8000000,尽管芯片以48MHz运行;结果是快速的SysTick。
3)如果我注释掉RCC_SYSCLKConfig()
调用,选择启动的HSI时钟,tmp
被分配为0x00,一切都按预期工作,芯片运行在8MHz,而不是48MHz我想要的。
4)如果我将其拔下几分钟,它将在第一次上电时正常工作,但在热复位(包括调试)时失效,或者在短时间内拔掉电源(~15秒)
5)我怀疑PLL初始化受温度影响。一个多月我没有在这个项目上工作,我的工作空间现在季节性变暖了。我在芯片上放了一小杯自来水,稍微冷却了芯片。这是成功的,因为程序每次都正确运行!取下杯子并用手指加热芯片后,它再次失败。
系统时钟配置的这种改变是否会以某种方式影响计算的完整性?我是否应该采取一些不同的措施来确保正确设置时钟?
答案 0 :(得分:1)
在开始之前,你是否放慢了速度?是的,我知道你之前没有使用更快的时钟,但也许它在乘以之前切换到1x的外部时钟。对闪存进行超频会导致奇怪的行为,虽然单步执行可能/应该仍然会导致一些奇怪的行为