Skip to main content
RN_it
Associate III
May 18, 2018
Question

GPIO timing issue in Timer ISR

  • May 18, 2018
  • 3 replies
  • 2360 views
Posted on May 18, 2018 at 12:11

Hello ,

I am toggling a gpio inside the timer ISR . the timer ISR triggers for every 1 sec.

Actually i am not able to see perfect 1 sec of gpio toggling . it also differs at different AHB frequency . i have included 2 cases with snapshot. please help me understand why i can not get perfect 1 sec gpio toggling and why it is different at 2 different ahb frequencies .

In the ISR i am just doing GPIOC->ODR ^= 0x2000U;

case 1 : AHB = 16Mhz HSI, Prescaler of timer = 999, period = 15999  ( in the image there is a difference of 10ms)

0690X0000060KpzQAE.png

case 2 : AHB= 50Mhz, Timer clock = 50Mhz, Prescaler of timer = 999, period = 49999 ( in the image there is a difference of 25ms)

0690X0000060KqnQAE.png

In both case it is showing different output . 

    This topic has been closed for replies.

    3 replies

    Nigel Meijer
    Associate
    May 18, 2018
    Posted on May 18, 2018 at 12:51

    A few things have effect on the crystal, Like temperature and supply voltage.

    For example in the STM32L083CZ datasheet on page 87:

    MSI oscillator frequency drift   0 °C ≤ TA ≤ 85 °C -  ±3

    A temperature between 0 and 85 degrees could cause a frequency drift of plus minus 3%

    Same happens with the supply voltage.

    Dont know why with different settings you get a different timing..
    Tesla DeLorean
    Guru
    May 18, 2018
    Posted on May 18, 2018 at 14:25

    Hard to replicate from screen shots. Define which STM32, and show code.

    Using HSE clock source?

    Can you try with a calibrated scope?

    Can you output internal clocks (HSI, HSE, PLL, etc) via MCO pin PA8, and scope those?

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    RN_it
    RN_itAuthor
    Associate III
    May 18, 2018
    Posted on May 18, 2018 at 15:23

     ,

     ,

    Hello Clive , ,

    Thanks for the reply . ,

    i am using stm32f446re nucleo board . , not using HSE. ,

    i am using saleae logic usb logic analyzer . i dont have a calibrated scope.

    HSI is 16Mhz verified using MCO. on MCO pin i can measure precisely ,

    here is code i used. ,

    int main(void)

     ,

    {

     ,

     ,

    HAL_Init(),

    SystemClock_Config(SYS_CLOCK_FREQ_50_MHZ),

     ,

     ,

    TIMER_Init(),

     ,

     ,

    GPIO_Init(),

     ,

     ,

    HAL_TIM_Base_Start_IT(&,htim6),

     ,

     ,

    while(1),

     ,

     ,

    return 0,

     ,

    }

    void GPIO_Init(void)

     ,

    {

     ,

    /* GPIO Ports Clock Enable */

     ,

    __HAL_RCC_GPIOC_CLK_ENABLE(),

     ,

    __HAL_RCC_GPIOH_CLK_ENABLE(),

     ,

    __HAL_RCC_GPIOA_CLK_ENABLE(),

     ,

    __HAL_RCC_GPIOB_CLK_ENABLE(),

     ,

     ,

    GPIO_InitTypeDef gpio_button,

     ,

    gpio_button.Mode = GPIO_MODE_OUTPUT_PP,

     ,

    gpio_button.Pin = GPIO_PIN_13,

     ,

    gpio_button.Pull = GPIO_NOPULL,

     ,

    gpio_button.Speed = GPIO_SPEED_FREQ_LOW,

     ,

    HAL_GPIO_Init(GPIOC,&,gpio_button),

     ,

    }

    void TIMER_Init(void)

     ,

    {

    TIM_MasterConfigTypeDef sMasterConfig,

     ,

    htim6.Instance = TIM6,

     ,

    htim6.Init.Prescaler = 999,

     ,

    htim6.Init.CounterMode = TIM_COUNTERMODE_UP,

     ,

    htim6.Init.Period = (50000-1),

     ,

    htim6.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1,

     ,

    if (HAL_TIM_Base_Init(&,htim6) != HAL_OK)

     ,

    {

     ,

    _Error_Handler(__FILE__, __LINE__),

     ,

    }

     ,

    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET,

     ,

    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE,

     ,

    if (HAL_TIMEx_MasterConfigSynchronization(&,htim6, &,sMasterConfig) != HAL_OK)

     ,

    {

     ,

    _Error_Handler(__FILE__, __LINE__),

     ,

    }

     ,

     ,

    }

    void SystemClock_Config(uint8_t clock_freq)

     ,

    {

     ,

    ♯ if 1

     ,

    RCC_OscInitTypeDef RCC_OscInitStruct,

     ,

    RCC_ClkInitTypeDef RCC_ClkInitStruct,

     ,

     ,

    /**Configure the main internal regulator output voltage

     ,

    */

     ,

    __HAL_RCC_PWR_CLK_ENABLE(),

    //__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3),

     ,

     ,

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI,

     ,

    RCC_OscInitStruct.HSIState = RCC_HSI_ON,

     ,

    RCC_OscInitStruct.HSICalibrationValue = 16,

     ,

    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON,

     ,

    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI,

    switch(clock_freq)

     ,

    {

     ,

    case SYS_CLOCK_FREQ_50_MHZ:

     ,

    RCC_OscInitStruct.PLL.PLLM = 8,

     ,

    RCC_OscInitStruct.PLL.PLLN = 50,

     ,

    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2,

     ,

    RCC_OscInitStruct.PLL.PLLQ = 2,

     ,

    RCC_OscInitStruct.PLL.PLLR = 2,

     ,

     ,

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

     ,

    |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2,

     ,

    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK,

     ,

    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1,

     ,

    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2,

     ,

    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1,

     ,

    break,

     ,

     ,

    case SYS_CLOCK_FREQ_84_MHZ:

     ,

    RCC_OscInitStruct.PLL.PLLM = 8,

     ,

    RCC_OscInitStruct.PLL.PLLN = 84,

     ,

    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2,

     ,

    RCC_OscInitStruct.PLL.PLLQ = 2,

     ,

    RCC_OscInitStruct.PLL.PLLR = 2,

     ,

     ,

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

     ,

    |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2,

     ,

    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK,

     ,

    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1,

     ,

    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2,

     ,

    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1,

     ,

    break,

     ,

     ,

    case SYS_CLOCK_FREQ_120_MHZ:

     ,

    RCC_OscInitStruct.PLL.PLLM = 8,

     ,

    RCC_OscInitStruct.PLL.PLLN = 120,

     ,

    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2,

     ,

    RCC_OscInitStruct.PLL.PLLQ = 2,

     ,

    RCC_OscInitStruct.PLL.PLLR = 2,

     ,

     ,

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

     ,

    |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2,

     ,

    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK,

     ,

    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1,

     ,

    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4,

     ,

    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2,

     ,

    break,

     ,

     ,

    default:

     ,

    return ,

     ,

     ,

    }

     ,

     ,

    if (HAL_RCC_OscConfig(&,RCC_OscInitStruct) != HAL_OK)

     ,

    {

     ,

    _Error_Handler(__FILE__, __LINE__),

     ,

    }

     ,

     ,

     ,

     ,

    if (HAL_RCC_ClockConfig(&,RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)

     ,

    {

     ,

    _Error_Handler(__FILE__, __LINE__),

     ,

    }

     ,

     ,

     ,

    /**Configure the Systick interrupt time

     ,

    */

     ,

    uint32_t hclk_freq = HAL_RCC_GetHCLKFreq(),

     ,

    HAL_SYSTICK_Config(hclk_freq/1000),

    /**Configure the Systick

     ,

    */

     ,

    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK),

    /* SysTick_IRQn interrupt configuration */

     ,

    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0),

    }

    /**

     ,

    * @brief This function handles TIM6 global interrupt and DAC1, DAC2 underrun error interrupts.

     ,

    */

     ,

    void TIM6_DAC_IRQHandler(void)

     ,

    {

     ,

    /* USER CODE BEGIN TIM6_DAC_IRQn 0 */

     ,

     ,

    //HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5),

     ,

    //GPIOC->,ODR ^= 0x2000U,

     ,

    GPIOC->,ODR ^= 0x2000U,

     ,

    /* USER CODE END TIM6_DAC_IRQn 0 */

     ,

    HAL_TIM_IRQHandler(&,htim6),

     ,

    /* USER CODE BEGIN TIM6_DAC_IRQn 1 */

    /* USER CODE END TIM6_DAC_IRQn 1 */

     ,

    }
    Tesla DeLorean
    Guru
    May 18, 2018
    Posted on May 18, 2018 at 15:29

    The Nucleo should be able to source an 8 MHz HSE via the ST-LINK

    The TIM should be able to drive a pin in toggle mode directly

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    John Craven
    Senior
    May 19, 2018
    Posted on May 19, 2018 at 17:37

    From the manual;

    6.2.2 HSI clock

    ...

    Calibration

    RC oscillator frequencies can vary from one chip to another due to manufacturing process variations, this is why each device is factory calibrated by ST for 1% accuracy at TA= 25 °C.

    Yor are getting results close to the factory specification.

    Have you calibrated the HSI better than 1%?

    Using HSE from ST-link on nucleo boards has always be much better than HSI in my experience (12-15 boards).