2014-01-27 10:37 AM
I'm new on stm32 development and I could be wrong.
I try to test the real core clock of my Stm32f4 discovery, using a modified example of IO_Ttoggle project of STM32F4-Discovery_FW_V1.1.0, using startup_stm32f4xx.s included without change. the essential part of my changes are SystemInit(); SystemCoreClockUpdate(); uint64_t timer=SystemCoreClock; while(1){ while(timer--) { } GPIO_ToggleBits(GPIOD, GPIO_Pin_13); timer=SystemCoreClock; } but this cycle require 9.x sec and not 1 sec, the configuration used was: stm32f4xxx.h: &sharpif !defined (HSE_VALUE) &sharpdefine HSE_VALUE ((uint32_t)8000000) /*!< not 25000000 as in original file */ &sharpendif /* HSE_VALUE */ /*@file stm32f4xx.h * @author MCD Application Team * @version V1.0.0 * @date 30-September-2011 */ and the system_stm32f4xx.c generated by the clock configuration tool /*============================================================================= *============================================================================= * Supported STM32F4xx device revision | Rev A *----------------------------------------------------------------------------- * System Clock source | PLL (HSE) *----------------------------------------------------------------------------- * SYSCLK(Hz) | 168000000 *----------------------------------------------------------------------------- * HCLK(Hz) | 168000000 *----------------------------------------------------------------------------- * AHB Prescaler | 1 *----------------------------------------------------------------------------- * APB1 Prescaler | 4 *----------------------------------------------------------------------------- * APB2 Prescaler | 2 *----------------------------------------------------------------------------- * HSE Frequency(Hz) | 8000000 *----------------------------------------------------------------------------- * PLL_M | 8 *----------------------------------------------------------------------------- * PLL_N | 336 *----------------------------------------------------------------------------- * PLL_P | 2 *----------------------------------------------------------------------------- * PLL_Q | 7 *----------------------------------------------------------------------------- * PLLI2S_N | 258 *----------------------------------------------------------------------------- * PLLI2S_R | 3 */ I tried also to change the manually the &sharpdefine PLL_M 16 or &sharpdefine PLL_P 4 to achive 84MHz but this have no effect always 9.x sec for every toggle. Using &sharpdefine PLL_M 16 (@ 84Mhz) and uint64_t timer=168 000 000; It takes 18.x sec. I think it's impossible that while(timer--) takes 10 clocks/cycle. during debugging the section SetSysClock() that say else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ } has never been reached, and SystemCoreClock was correctly update douring the test @84 Mhz it seems that the core clock always run at 1/10 of indicated speed 16.xMhz @168Mhz and 8.xMhz @84Mhz Where i'm wrong? #clock #stm32f42014-01-27 12:42 PM
I think it's impossible that
while(timer--)
takes 10 clocks/cycle. That would depend a lot on what code the compiler actually generated, the optimization settings, and the fact the CPU doesn't natively support 64-bit math. So perhaps not an assumption you're qualified to make.If you want to measure the internal clocks, then output them via the MCOx pins and look at them on a scope.If you want to mark time, use a timer, or SysTick reference which has some defined basis rather than some arbitrary software delay loop.
2014-01-27 11:37 PM
Thanks Clive1!
(these tests
were done
waiting for
the oscilloscope
that
is
lost somewhere
in the world
)2014-01-28 06:19 AM
For delays that relate to the CPU clock speed, consider using DWT_CYCCNT
//******************************************************************************
volatile unsigned int *DWT_CYCCNT = (volatile unsigned int *)0xE0001004; //address of the register
volatile unsigned int *DWT_CONTROL = (volatile unsigned int *)0xE0001000; //address of the register
volatile unsigned int *SCB_DEMCR = (volatile unsigned int *)0xE000EDFC; //address of the register
//******************************************************************************
void EnableTiming(void)
{
*SCB_DEMCR = *SCB_DEMCR | 0x01000000;
*DWT_CYCCNT = 0; // reset the counter
*DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter
}
//******************************************************************************
void TimingDelay(unsigned int tick)
{
unsigned int start, current;
start = *DWT_CYCCNT;
do
{
current = *DWT_CYCCNT;
} while((current - start) < tick);
}
//******************************************************************************