AnsweredAssumed Answered

Systick and TIM6

Question asked by Konstantin Maslennikov on Feb 19, 2018
Latest reply on Feb 19, 2018 by Konstantin Maslennikov

I have stm32f4-disco.

I'm try use timers and systick for delay.

It's my main.c:

#include "stm32f4xx.h"

#define GREEN_LED_On()         GPIOD->BSRR |= GPIO_BSRR_BS12
#define GREEN_LED_Off()         GPIOD->BSRR |= GPIO_BSRR_BR12
#define GREEN_LED_Toggle()      GPIOD->ODR ^= GPIO_ODR_ODR_12

#define ORANGE_LED_On()         GPIOD->BSRR |= GPIO_BSRR_BS13
#define ORANGE_LED_Off()      GPIOD->BSRR |= GPIO_BSRR_BR13
#define ORANGE_LED_Toggle()      GPIOD->ODR ^= GPIO_ODR_ODR_13

#define TIMER               1000
#define F_APB1               42000000UL

uint32_t TimingDelay = 0;

void RCC_Init(void);
void LED_Init(void);
void delay_ms(uint16_t delay);

int main(void)
{
   RCC_Init();
   
   RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
   
   SystemCoreClockUpdate();
   SysTick_Config(SystemCoreClock / 1000);

   LED_Init();
   
   while (1)
   {
      GREEN_LED_Toggle();         // Channel 0
      delay_ms(TIMER);
      GREEN_LED_Toggle();
      delay_ms(TIMER);
      
      if ((TimingDelay % TIMER) == 0)
      {
         ORANGE_LED_Toggle();   // Channel 1
         TimingDelay = 0;
      }
      
   }

}

void SysTick_Handler() {
   TimingDelay++;
}


void delay_ms(uint16_t delay) {  
   
   TIM6->PSC = (F_APB1 / 1000) - 1;
   TIM6->ARR = (delay) - 1;
   TIM6->EGR |= TIM_EGR_UG;
   TIM6->CR1 |= TIM_CR1_OPM;
   TIM6->CR1 |= TIM_CR1_CEN;
   while ((TIM6->CR1 & TIM_CR1_CEN) != 0);
   
}

 

void LED_Init(void) {
   /* Enable GPIO */
   RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
   
   /* Configure GPIOD12 as output, medium speed, no pull-up, pull-down */
   GPIOD->MODER    &=    ~GPIO_MODER_MODER12_1;
   GPIOD->MODER    |=     GPIO_MODER_MODER12_0;
   GPIOD->OTYPER   &=    ~GPIO_OTYPER_OT_12;
   GPIOD->PUPDR    &=    ~GPIO_PUPDR_PUPDR12;
   GPIOD->OSPEEDR    |=     GPIO_OSPEEDER_OSPEEDR12_0;
   GPIOD->OSPEEDR    &=    ~GPIO_OSPEEDER_OSPEEDR12_1;

   /* Configure GPIOD13 as output, medium speed, no pull-up, pull-down */
   GPIOD->MODER    &=    ~GPIO_MODER_MODER13_1;
   GPIOD->MODER    |=     GPIO_MODER_MODER13_0;
   GPIOD->OTYPER   &=    ~GPIO_OTYPER_OT_13;
   GPIOD->PUPDR    &=    ~GPIO_PUPDR_PUPDR13;
   GPIOD->OSPEEDR    |=     GPIO_OSPEEDER_OSPEEDR13_0;
   GPIOD->OSPEEDR    &=    ~GPIO_OSPEEDER_OSPEEDR13_1;   


void RCC_Init(void) { 
   
   RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM;
   RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN;
   RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP;
   RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLQ;
   RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLSRC;

   RCC->CR |= RCC_CR_HSEON;                                      // Enable HSE
   while (!(RCC->CR & RCC_CR_HSERDY)) {}                   // Wait for ready HSE                                          
      
   RCC->CFGR |= RCC_CFGR_HPRE_DIV1;                     // AHB = SYSCLK/1 = 168MHz
   RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;                   // APB1 = HCLK/4 (PCLK1 = 42 MHz, APB1 Timers = 84 MHz)
   RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;                   // APB2 = HCLK/2 (PCLK2 = 84 MHz, APB2 Timers = 168 MHz)
   
   RCC->PLLCFGR |= RCC_PLLCFGR_PLLM_2;                 // PLLM = 4
   RCC->PLLCFGR |= (RCC_PLLCFGR_PLLN_3 | RCC_PLLCFGR_PLLN_5 
                              | RCC_PLLCFGR_PLLN_7);                     // PLLN = 168
      
   RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP;                     // PLLP = 2
      
   RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC;                     // HSE oscillator clock selected as PLL and PLLI2S clock entry
      
   RCC->PLLCFGR |= (RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLQ_1
                                | RCC_PLLCFGR_PLLQ_2);   // PLLQ = 7
   
   RCC->CR |= RCC_CR_PLLON;                                  // Enable PLL
   while (!(RCC->CR & RCC_CR_PLLRDY)) {}                     // Wait till PLL is ready
      
   FLASH->ACR |= FLASH_ACR_ICEN | FLASH_ACR_DCEN \
                              | FLASH_ACR_LATENCY_5WS \
                         | FLASH_ACR_PRFTEN;         // Clock Flash memory

   RCC->CFGR &= ~RCC_CFGR_SW;
   RCC->CFGR |= RCC_CFGR_SW_PLL;                        // PLL selected as system clock   
   while (!(RCC->CFGR & RCC_CFGR_SWS_PLL)) {}               // Wait for PLL/PLLP used as system clock  
    }
}

If I try increase interval in timer  (TIM6->ARR = (delay * 2) - 1;) interval in systick

      if ((TimingDelay % TIMER) == 0)
      {
         ORANGE_LED_Toggle();   // Channel 1
         TimingDelay = 0;
      }
 

void SysTick_Handler() {
   TimingDelay++;
}

is increase twice...  Why?

Outcomes