cancel
Showing results for 
Search instead for 
Did you mean: 

TIMER with discovery

joesoftware
Associate II
Posted on March 14, 2013 at 20:07

I modify TIM Time Base example for learn more about timer, i blink led with timer, my code works well but i didn't understand instructions

This is my code:

/** 
****************************************************************************** 
* @file TIM/TimeBase/main.c 
* @author MCD Application Team 
* @version V3.5.0 
* @date 08-April-2011 
* @brief Main program body 
****************************************************************************** 
* @attention 
* 
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 
* 
* <
h2
><
center
>© COPYRIGHT 2011 STMicroelectronics</
center
></
h2
> 
****************************************************************************** 
*/ 
/* Includes ------------------------------------------------------------------*/ 
#include ''stm32f10x.h'' 
#include ''stm32vldiscovery.h'' 
/** @addtogroup STM32F10x_StdPeriph_Examples 
* @{ 
*/ 
/** @addtogroup TIM_TimeBase 
* @{ 
*/ 
/* Private typedef -----------------------------------------------------------*/ 
/* Private define ------------------------------------------------------------*/ 
/* Private macro -------------------------------------------------------------*/ 
/* Private variables ---------------------------------------------------------*/ 
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
TIM_OCInitTypeDef TIM_OCInitStructure; 
__IO uint16_t CCR1_Val = 40961; 
uint16_t PrescalerValue = 0; 
/* Private function prototypes -----------------------------------------------*/ 
void RCC_Configuration(void); 
void GPIO_Configuration(void); 
void NVIC_Configuration(void); 
/* Private functions ---------------------------------------------------------*/ 
/** 
* @brief Main program 
* @param None 
* @retval None 
*/ 
int main(void) 
{ 
/*!< At this stage the microcontroller clock setting is already configured, 
this is done through SystemInit() function which is called from startup 
file (startup_stm32f10x_xx.s) before to branch to application main. 
To reconfigure the default setting of SystemInit() function, refer to 
system_stm32f10x.c file 
*/ 
/* System Clocks Configuration */ 
RCC_Configuration(); 
/* NVIC Configuration */ 
NVIC_Configuration(); 
/* GPIO Configuration */ 
GPIO_Configuration(); 
STM32vldiscovery_LEDOn(LED3); 
STM32vldiscovery_LEDOff(LED4); 
/* Compute the prescaler value */ 
PrescalerValue = (uint16_t) (SystemCoreClock / 12000000) - 1; 
/* Time base configuration */ 
TIM_TimeBaseStructure.TIM_Period = 65535; 
TIM_TimeBaseStructure.TIM_Prescaler = 0 ; 
TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 
/* Prescaler configuration */ 
TIM_PrescalerConfig(TIM2, PrescalerValue, TIM_PSCReloadMode_Immediate); 
/* Output Compare Timing Mode configuration: Channel1 */ 
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; 
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
TIM_OCInitStructure.TIM_Pulse = CCR1_Val; 
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
TIM_OC1Init(TIM2, &TIM_OCInitStructure); 
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); 
/* TIM IT enable */ 
TIM_ITConfig(TIM2, TIM_IT_CC1 , ENABLE); 
/* TIM2 enable counter */ 
TIM_Cmd(TIM2, ENABLE); 
while (1); 
} 
/** 
* @brief Configures the different system clocks. 
* @param None 
* @retval None 
*/ 
void RCC_Configuration(void) 
{ 
/* PCLK1 = HCLK/4 */ 
RCC_PCLK1Config(RCC_HCLK_Div16); 
/* TIM2 clock enable */ 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 
/* GPIOC clock enable */ 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); 
} 
/** 
* @brief Configure the GPIO Pins. 
* @param None 
* @retval None 
*/ 
void GPIO_Configuration(void) 
{ 
GPIO_InitTypeDef GPIO_InitStructure; 
/* GPIOC Configuration:Pin 8 and 9 as alternate function push-pull */ 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
GPIO_Init(GPIOC, &GPIO_InitStructure); 
} 
/** 
* @brief Configure the nested vectored interrupt controller. 
* @param None 
* @retval None 
*/ 
void NVIC_Configuration(void) 
{ 
NVIC_InitTypeDef NVIC_InitStructure; 
/* Enable the TIM2 global Interrupt */ 
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_Init(&NVIC_InitStructure); 
} 
#ifdef USE_FULL_ASSERT 
/** 
* @brief Reports the name of the source file and the source line number 
* where the assert_param error has occurred. 
* @param file: pointer to the source file name 
* @param line: assert_param error line source number 
* @retval None 
*/ 
void assert_failed(uint8_t* file, uint32_t line) 
{ 
/* User can add his own implementation to report the file name and line number, 
ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */ 
while (1) 
{} 
} 
#endif 
/** 
* @} 
*/ 
/** 
* @} 
*/ 
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 

My problems are: if TIM2 counter clock at 24/16 and CC1 update rate = TIM2 counter clock / CCR1_Val How can i chose TIM_TimeBaseStructure.TIM_Period = 65535; what will i change if i use another value? And why more instruction about prescale? PrescalerValue = (uint16_t) (SystemCoreClock / 1200000) - 1; TIM_TimeBaseStructure.TIM_Prescaler = 0 ; whats the different use of that? If i want 500ms timer how can i configure this value? Thanks
6 REPLIES 6
Posted on March 15, 2013 at 00:49

So where is the interrupt handler? Are you advancing the TIM2->CCR1 to generate the frequency?

Your TIM2 clock is probably 3 MHz, if the CPU is running at 24 MHz, look at the clock tree in the manual to understand this relationship.

Generating 2 Hz from 3 MHz, you'd need to divide the source by 1500000 which won't fit in 16 bit.

I personally would use the Update interrupt, Set the Period to 50000-1 and Prescale to 30-1, this is achieved with some rudimentary factoring, there are dozens of other combinations that would work.

2 x 50000 x 30 = 3 MHz
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
joesoftware
Associate II
Posted on March 15, 2013 at 09:39

Thanks clive1

This is my interrupt handler

void TIM2_IRQHandler(void) 
{ 
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) 
{ 
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); 
STM32vldiscovery_LEDToggle(LED3); 
STM32vldiscovery_LEDToggle(LED4); 
} 
}

I understand what u wrote. I can't understand why 3MHZ i think /* PCLK1 = HCLK/16 */ RCC_PCLK1Config(RCC_HCLK_Div16); generates 1.5MHz? If i want to set prescalevalue to 30 what instruction need to change? i can't understand why i have 2 instruction different: /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 1200000) - 1; and TIM_TimeBaseStructure.TIM_Prescaler = 0 ; Last One thing where i use

CCR1_Val = 40961;

if all my clock was configured to 2 x 50000 x 30 = 3 MHz i read in help of this code that he use CC1 update rate = TIM2 counter clock / CCR1_Val Thanks
Posted on March 15, 2013 at 10:05

The code changes the prescaler later, but I think you need to re-read the chapter on timers in the manual. It is the period/prescale value that alter the periodicity of the counter, the output compare could be used for phase, but will not generate a frequency unless you keep advancing the trigger point.

For a simple 2 Hz interrupt, from a 24 MHz * 2 / 16 clock the following should suffice.

#include ''stm32f10x.h''
#include ''stm32vldiscovery.h''
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
int main(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* System Clocks Configuration */
RCC_Configuration();
/* NVIC Configuration */
NVIC_Configuration();
/* GPIO Configuration */
GPIO_Configuration();
STM32vldiscovery_LEDOn(LED3);
STM32vldiscovery_LEDOff(LED4);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 50000-1;
TIM_TimeBaseStructure.TIM_Prescaler = 30-1 ;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* TIM IT enable */
TIM_ITConfig(TIM2, TIM_IT_Update , ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
while (1);
}
void RCC_Configuration(void)
{
/* PCLK1 = HCLK/4 */
RCC_PCLK1Config(RCC_HCLK_Div16);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOC clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOC Configuration:Pin 8 and 9 as push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
STM32vldiscovery_LEDToggle(LED3);
STM32vldiscovery_LEDToggle(LED4);
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 15, 2013 at 10:12

I can't understand why 3MHZ i think  

 

/* PCLK1 = HCLK/16 */

 

  RCC_PCLK1Config(RCC_HCLK_Div16);

 

generates 1.5MHz?

 

 

From the Clock Tree in the Reference Manual

0690X00000605GsQAI.png
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
joesoftware
Associate II
Posted on March 15, 2013 at 10:34

Thanks

for your patience.

I forgot that

apb1

doubles the

clock

timers

.

I will read again timer chapter, i think now it will be more easy.

Thanks

Posted on March 15, 2013 at 11:06

The description is a bit deceptive, it doesn't really double it, rather it takes a clock from further up the divider chain. So the operation isn't /16 then x2 but rather just /8

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..