Associate
November 26, 2021
Solved
[SOLVED] NUCLEO F207ZG TIM6 timer half speed using CMSIS
- 5 replies
- 2987 views
Hello,
I need to perform some task without using HAL libraries. I am using CMSIS.
To start, I have set up a blinking led with timer.
I programmed the clock as per attached picture. The source clock of TIM6 should be 60 MHz but the led behaves as it were 30 MHz. It blinks at half the speed.
When I expect 500ms delay, the led stays on (or off) 1s. I don't' understand where this factor 2 comes from.
What am I doing wrong?
Here is the code
#include <stdint.h>
#include "stm32f2xx.h"
#if !defined(__SOFT_FP__) && defined(__ARM_FP)
#warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif
static void SystemClock_Config();
void TIM6Config (void);
void Delay_us (uint16_t us);
void Delay_ms (uint16_t ms);
int main(void)
{
// uint32_t i;
SystemClock_Config();
//NVIC_SetPriority
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
GPIOB->MODER |= 0x01 << GPIO_MODER_MODER14_Pos;
GPIOB->OSPEEDR |= 0x01 << 29;
//uart (not yet implemented, to be completed)
//ENABLE PORT D AND USART 3
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
GPIOD->AFR[1] |= (7<<0); //ALTERNATE PD8
GPIOD->AFR[1] |= (7<<4); //ALTERNATE PD9
GPIOD->OSPEEDR |= (3<<16) | (3<<18); //HIGH SPEED FOR PD8 AND PD9
TIM6Config ();
/* Loop forever */
while(1) {
GPIOB->ODR ^= GPIO_ODR_ODR_14;
Delay_ms (500);
}
}
static void SystemClock_Config()
{
#define PLL_M_SETTING 8
#define PLL_N_SETTING 240
#define PLL_P_SETTING 0 //PLLP = 2
// Start HSE in Bypass Mode
RCC->CR |= RCC_CR_HSEBYP;
RCC->CR |= RCC_CR_HSEON;
while(!(RCC->CR & RCC_CR_HSERDY));
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
RCC->PLLCFGR |= (PLL_M_SETTING << 0) | (PLL_N_SETTING << 6) | (PLL_P_SETTING << 16) | (RCC_PLLCFGR_PLLSRC_HSE);
RCC->CR |= RCC_CR_PLLON;
while(!(RCC->CR & RCC_CR_PLLRDY));
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
SystemCoreClockUpdate();
}
void TIM6Config (void)
{
// 1. Enable Timer clock
RCC->APB1ENR |= (1<<4); // Enable the timer6 clock
// 2. Set the prescalar and the ARR
TIM6->PSC = 60-1; // 1 MHz ~~ 1 uS delay
TIM6->ARR = 0xffff; // MAX ARR value
// 3. Enable the Timer, and wait for the update Flag to set
TIM6->CR1 |= (1<<0); // Enable the Counter
while (!(TIM6->SR & (1<<0)));
}
void Delay_us (uint16_t us)
{
TIM6->CNT = 0;
while (TIM6->CNT < us);
}
void Delay_ms (uint16_t ms)
{
for (uint16_t i=0; i<ms; i++)
{
Delay_us (1000); // delay of 1 ms
}
}