AnsweredAssumed Answered

LL_mDelay taking an extra millisecond?

Question asked by Sam Walsh on Aug 15, 2017
Latest reply on Aug 15, 2017 by Clive One

Hi, I am using a Nucleo F401RE running at 84 MHz  (8 MHz XTAL PLL'd up to 84 MHz) and then using Timer 2 as a simple counter to count how long it takes to run the delays.

 

Timer 2 is set to run at 84 MHz with no prescaler and I am using LL_mDelay for the delays. I have a function which converts the counts to milliseconds. You can see in the timer2 function I am simply reading the count, delaying and resetting the count. However every one of my LL_mDelays are a millisecond over what they should be.

 

Eg LL_mDelay(1) takes 2 milliseconds, LL_mDelay(0) takes 1 millisecond.

 

Any ideas why this is? I have attached the watch window output and the project as a zip.

#include "main.h"

void SystemClock_Config(void);
void Configure_Timer2(void);
float Counts_To_Ms(uint32_t);

volatile uint32_t Counts[10];
volatile float Counts_ms[10];
int main(void)
{
/* Configure the system clock to 84 MHz */
SystemClock_Config();

/* Configure Timer 2 as a software start stop timer */
Configure_Timer2();


/* Infinite loop */
while (1)
{
}
}

float Counts_To_Ms(uint32_t count){
return ((1.0/84000000) * count) * 1000;
}
void Configure_Timer2(void){
// Timer 2 peripheral Configuration
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); // Enable clock to Timer 2 peripheral
/* Enable counter */
LL_TIM_EnableCounter(TIM2);

//First Count
LL_mDelay(0);
Counts[0] = LL_TIM_GetCounter(TIM2);
Counts_ms[0] = Counts_To_Ms(Counts[0]);
LL_TIM_SetCounter(TIM2, 0);

//Second Count
LL_mDelay(1);
Counts[1] = LL_TIM_GetCounter(TIM2);
Counts_ms[1] = Counts_To_Ms(Counts[1]);
LL_TIM_SetCounter(TIM2, 0);

//Third Count
LL_mDelay(2);
Counts[2] = LL_TIM_GetCounter(TIM2);
Counts_ms[2] = Counts_To_Ms(Counts[2]);
LL_TIM_SetCounter(TIM2, 0);

//Fourth Count
LL_mDelay(3);
Counts[3] = LL_TIM_GetCounter(TIM2);
Counts_ms[3] = Counts_To_Ms(Counts[3]);
LL_TIM_SetCounter(TIM2, 0);

//Fifth Count
LL_mDelay(4);
Counts[4] = LL_TIM_GetCounter(TIM2);
Counts_ms[4] = Counts_To_Ms(Counts[4]);
LL_TIM_SetCounter(TIM2, 0);

//Sixth Count
LL_mDelay(5);
Counts[5] = LL_TIM_GetCounter(TIM2);
Counts_ms[5] = Counts_To_Ms(Counts[5]);
LL_TIM_SetCounter(TIM2, 0);

//Seventh Count
LL_mDelay(6);
Counts[6] = LL_TIM_GetCounter(TIM2);
Counts_ms[6] = Counts_To_Ms(Counts[6]);
LL_TIM_SetCounter(TIM2, 0);
__nop();

}
/**
* The system Clock is configured as follow :
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 84000000
* HCLK(Hz) = 84000000
* AHB Prescaler = 1
* APB1 Prescaler = 1
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 8000000
* PLL_M = 8
* PLL_N = 336
* PLL_P = 4
* VDD(V) = 3.3
* Main regulator output voltage = Scale2 mode
* Flash Latency(WS) = 2
*/

void SystemClock_Config(void)
{
/* Enable HSE oscillator */
LL_RCC_HSE_EnableBypass();
LL_RCC_HSE_Enable();
while(LL_RCC_HSE_IsReady() != 1){};
/* Set FLASH latency */
LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
/* Main PLL configuration and activation */
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_8, 336, LL_RCC_PLLP_DIV_4);
LL_RCC_PLL_Enable();
while(LL_RCC_PLL_IsReady() != 1){};
/* Sysclk activation on the main PLL */
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL){};
/* Set APB1 & APB2 prescaler */
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
/* Set systick to 1us */
SysTick_Config(84000000 / 1000);
/* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */
SystemCoreClock = 84000000;
}

Outcomes